Boost logo

Boost :

From: Andrey Semashev (andysem_at_[hidden])
Date: 2005-08-21 15:41:23


Sometimes it is very useful to register some postponed actions regardless of
some part of the program result (a function, for example). Smart pointers
are obvious example of such actions (namely, freeing resources) and in fact
are a special case of so called scope guards. Guards may be especially
useful in heavilly-logical code with multiple (maybe folded into each other)
checks or in code using exceptions.

As a simple example, suppose we have a logging system that may trace
function calls in our program. The easiest and obvious way to implement such
functionality is to create some object in the beginning of each function to
be traced. This object will add the function to the logger on its
construction and remove it on destruction.
Another application is resolving circular calling dependency issues which
tend to come up in rather complex projects. The following example
illustrates the problem:

class A;

// The objects of class B are managed by object of class A
class B {
public:
    void execute(A* pA, int n);
};

// The object of main class A manages some other objects of class B
class A {
    // Some internal data, which is provided to the managed objects
    std::set< int > m_Data;

public:
    // The entrance method, called from somewhere outside
    void process(B* pB) {
        // Imagine we have some real processing here and m_Data is not empty
        pB->execute(this, *m_Data.begin());
        // Here we cannot be absolutely sure if m_Data still contains the
element we passed in line above
    }

    void remove(int n) {
        m_Data.erase(n);
    }
};

void B::execute(A* pA, int n) {
    if (n > 10)
        pA->remove(n);
}

The case above is usually fixed by using some kind of state variables or
flags or, in more complex cases, some stacks of postprocessing. I.e. in
A::remove we don't actually erase the element but schedule some action to
perform when control returns to A::process. This can easily be done by
enqueued functors or scope guards. In some cases the latter are simplier to
use and more laconic.

I purpose to add a generalized scope guard classes to the Boost library. I
have a rather simple but flexible implementation of such classes (I've
attached the sources). Since I'm new here, I don't really know if they
conform some source code conventions in Boost (if any), but if they don't -
please, let me know.

Few general words about the implementation. There are two general guard
classes: leaving_scope_guard and scope_guard. The first one calls a functor
(boost::function is used) with no arguments on its destruction if it is
armed. The second class extends the first one by calling another functor on
its construction (this is not a functionality of real necessity, but it
allows to semantically group paired functions invocation, see the example
above). A guard once created may be armed or disarmed later in thÕ program,
but the armed status applies only to the destructing functor invoking (the
constructing one is controlled via initial status of the guard which is
passed in guard constructor arguments).
The flexibility of implementation is in ability to change the functors
invoking policy. In the simpliest case it is a direct invoking (all template
parameters by default), but there is a policy with exception catching
support. See the example:

struct my_exception : public std::exception { /* ... */ };

void guarded_foo(int n, const char* p); // throws bad_cast, bad_alloc and
my_exception

// This is the class of the exception handler object
struct CHandler {
    void on_exception(std::bad_cast& e) throw() {
        std::cout << "on_exception called, bad_cast caught" << std::endl;
    }
    void on_exception(std::bad_alloc& e) throw() {
        std::cout << "on_exception called, bad_alloc caught" << std::endl;
    }
    void on_exception(my_exception& e) throw() {
        std::cout << "on_exception called, my_exception caught" <<
std::endl;
    }
};

void foo(int n) {
    leaving_scope_guard<
        guard::with_catcher< // Indicate that we're expecting some
exceptions to be thrown by guarded_foo
            CHandler, // This is the class, which object is to process
exceptions caught
            guard::exceptions< std::bad_cast, std::bad_alloc, my_exception
>, // Exceptions to be caught (up to 10 exception types supported)
            boost::shared_ptr< CHandler > // An optional parameter describes
the way the pointer to CHandler object should be stored. The default value
would be CHandler*.
>
> guard(boost::bind(&guarded_foo, n, "called from foo"),
boost::shared_ptr< CHandler >(new CHandler)); // Guard object

    // ...
}

There also are macroses defined for setting anonymous scope guards when
there is no need for arming or disarming it.

As for compatibility, I successfully compiled it on VC 7.1, ICC 9.0 and GCC
3.4.4 (MinGW version). I don 't think it will compile on VC 6 since explicit
template function instantiation is used there which is not supported by the
compiler, but I think it is possible to work around it. Besides that I don't
think there should be any problems for other compilers.

Any suggestions are welcome.

begin 666 scope_guard.h
M+RHA#0H@*B!<9FEL92 @('-C;W!E7V=U87)D+F_at_-"B J(%QA=71H;W(@4V5M
M87-H978_at_06YD<F5Y#0H@*B!<9&%T92 @(#(U+C W+C(P,#4-"B J( T*("H@
M7&)R:65F("!'96YE<F%L:7IE9"!S8V]P92!G=6%R9"!D96-L87)A=&EO;@T*
M("H@#0H@*B\-"@T*(VEF;F1E9B!?7U-#3U!%1U5!4D1?2%]?#0HC9&5F:6YE
M(%]?4T-/4$5'54%21%](7U\-"@T*(VEN8VQU9&4@(F)O;W-T+V9U;F-T:6]N
M+V9U;F-T:6]N,"YH<' B#0HC:6YC;'5D92 B8F]O<W0O;F]N8V]P>6%B;&4N
M:'!P(@T*(VEN8VQU9&4@(F)O;W-T+W1Y<&5?=')A:71S+VES7V)A<V5?86YD
M7V1E<FEV960N:'!P(@T*(VEN8VQU9&4@(F)O;W-T+W1Y<&5?=')A:71S+VES
M7W!O:6YT97(N:'!P(@T*#0HO+R!-86-R;W-E<R!F;W(@9V5N97)A=&EN9R!R
M96=U;&%R(&-O9&4-"B-D969I;F4_at_7U]30T]015]'54%21%]%3E5-15)!5$5?
M34%#4D]?*&EM<&Q?;6%C<F\I7 T*"6EM<&Q?;6%C<F\H,2E<#0H):6UP;%]M
M86-R;R_at_R*5P-"@EI;7!L7VUA8W)O*#,I7 T*"6EM<&Q?;6%C<F\H-"E<#0H)
M:6UP;%]M86-R;R_at_U*5P-"@EI;7!L7VUA8W)O*#8I7 T*"6EM<&Q?;6%C<F\H
M-RE<#0H):6UP;%]M86-R;R_at_X*5P-"@EI;7!L7VUA8W)O*#DI#0H-"B-D969I
M;F4_at_7U]30T]015]'54%21%]%3E5-15)!5$5?34%#4D\H:6UP;%]M86-R;RE<
M#0H):6UP;%]M86-R;R_at_P*5P-"@E?7U-#3U!%7T=505)$7T5.54U%4D%415]-
M04-23U\H:6UP;%]M86-R;RD-"@T*(V1E9FEN92!?7U-#3U!%7T=505)$7TY5
M3$Q465!%4RAI=&5R*2!S=')U8W0@;G5L;'1Y<&4C(VET97(@.B!P=6)L:6,@
M;G5L;'1Y<&4@>WT[#0HC9&5F:6YE(%]?4T-/4$5?1U5!4D1?5$5-4$Q!5$5?
M4$%204U3*&ET97(I("P@='EP96YA;64_at_17AC97!T:6]N5",C:71E<B ](&1E
M=&%I;#HZ;G5L;'1Y<&4C(VET97(-"B-D969I;F4_at_7U]30T]015]'54%21%]4
M65!%1$5&4RAI=&5R*2!T>7!E9&5F($5X8V5P=&EO;E0C(VET97(@97AC97!T
M:6]N7W1Y<&4C(VET97([#0HC9&5F:6YE(%]?4T-/4$5?1U5!4D1?0T%40TA%
M4RAI=&5R*5P-"@EC871C:" H='EP96YA;64_at_17AC97!T:6]N<TQI<W14.CIE
M>&-E<'1I;VY?='EP92,C:71E<B F(&4I('M<#0H)"71Y<&5D968_at_9&5T86EL
M.CI'=6%R9$AE;'!E<CP@='EP96YA;64_at_17AC97!T:6]N<TQI<W14.CIE>&-E
M<'1I;VY?='EP92,C:71E<B ^($AE;'!E<E]T.UP-"@D)2&5L<&5R7W0Z.FEN
M=F]K95]E>&-E<'1I;VY?:&%N9&QE<CP_at_97AC97!T:6]N<U]H86YD;&5R7W!O
M:6YT97)?='EP92 ^*&U?<$AA;F1L97(L(&4I.UP-"@E]#0H-"FYA;65S<&%C
M92!B;V]S="![#0H-"FYA;65S<&%C92!G=6%R9"![#0H-"B\O(2!%;G5M97)A
M=&EO;B!O9B!S=&%T=7-E<R!O9B!G=6%R9 T*96YU;2!E;G5M4V-O<&5'=6%R
M9%-T871U<R![#0H)87)M960@/2!F86QS92P-"@ED:7-A<FUE9" ]('1R=64-
M"GT[#0H-"FYA;65S<&%C92!D971A:6P@>PT*#0H)+R\A($5M<'1Y('-T<G5C
M='5R97,@9F]R(&EN9&EC871I;VX@;V8@='EP92!A8G-E;F-E#0H)<W1R=6-T
M(&YU;&QT>7!E('M].PT*"5]?4T-/4$5?1U5!4D1?14Y53452051%7TU!0U)/
M7RA?7U-#3U!%7T=505)$7TY53$Q465!%4RD-"@T*"2\O(2!4:&ES(&-L87-S
M(&1E=&5C=',@=&AE(&]P=&EM86P@<&%R86UE=&5R('1Y<&4@;V8@<&]I;G1E
M<B!T;R!E>&-E<'1I;VX@:&%N9&QE<B!O8FIE8W0-"@ET96UP;&%T93P@='EP
M96YA;64_at_5"P_at_8F]O;"!F4&]I;G1E<B ](&)O;W-T.CII<U]P;VEN=&5R/"!4
M(#XZ.G9A;'5E(#X-"@ES=')U8W0@<&]I;G1E<E]T>7!E('L-"@D)='EP961E
M9B!4(&-O;G-T)B!T>7!E.PT*"7T[#0H)=&5M<&QA=&4\('1Y<&5N86UE(%0@
M/@T*"7-T<G5C="!P;VEN=&5R7W1Y<&4\(%0L('1R=64@/B![#0H)"71Y<&5D
M968_at_5"!T>7!E.PT*"7T[#0H-"@DO+R$@17AC97!T:6]N(&AA;F1L97(@:6YV
M;VMI;F<@:&5L<&5R#0H)=&5M<&QA=&4\('1Y<&5N86UE(%0L(&)O;VP_at_9DYU
M;&Q4>7!E(#T_at_8F]O<W0Z.FES7V)A<V5?86YD7V1E<FEV960\(&YU;&QT>7!E
M+"!4(#XZ.G9A;'5E(#X-"@ES=')U8W0_at_1W5A<F1(96QP97(@>PT*"0ET96UP
M;&%T93P@='EP96YA;64_at_52 ^#0H)"0ES=&%T:6,@:6YL:6YE('9O:60@:6YV
M;VME7V5X8V5P=&EO;E]H86YD;&5R*'1Y<&5N86UE('!O:6YT97)?='EP93P@
M52 ^.CIT>7!E('!(86YD;&5R+"!4)B!E*2![#0H)"0DO+R!)9B!T:&4_at_9F]L
M;&]W:6YG(&QI;F4_at_9F%I;',@=&\@8V]M<&EL92!T:&5N('1H97)E(&ES(&%N
M(&5X8V5P=&EO;B!T>7!E+"!F;W(@=VAI8V_at_-"@D)"2\O(&]N7V5X8V5P=&EO
M;B!F=6YC=&EO;B!I<R!N;W0_at_9&5F:6YE9"!I;B!E>&-E<'1I;VX@:&%N9&QE
M<B!C;&%S<PT*"0D):68@*'!(86YD;&5R*2!P2&%N9&QE<BT^;VY?97AC97!T
M:6]N*&4I.PT*"0E]#0H)?3L-"@ET96UP;&%T93P@='EP96YA;64_at_5" ^#0H)
M<W1R=6-T($=U87)D2&5L<&5R/"!4+"!T<G5E(#X@>PT*"0ET96UP;&%T93P@
M='EP96YA;64_at_52 ^#0H)"7-T871I8R!I;FQI;F4@=F]I9"!I;G9O:V5?97AC
M97!T:6]N7VAA;F1L97(H='EP96YA;64@<&]I;G1E<E]T>7!E/"!5(#XZ.G1Y
M<&4L(%0F*2![#0H)"7T-"@E].PT*#0H)+R\A(%1H92!C;&%S<R!H;VQD<R!A
M;F0@;6%N86=E<R!T:&4@<W1A='5S(&]F('1H92!G=6%R9 T*"6-L87-S('-C
M;W!E7V=U87)D7W1R:6=G97(-"@E[#0H)<')O=&5C=&5D._at_T*"0DO+R$@1W5A
M<F0G<R!S=&%T=7,-"@D)96YU;5-C;W!E1W5A<F13=&%T=7,@;5]3=&%T=7,[
M#0H)<'5B;&EC._at_T*"0ES8V]P95]G=6%R9%]T<FEG9V5R*&5N=6U38V]P94=U
M87)D4W1A='5S(%-T871U<RD_at_.B!M7U-T871U<RA3=&%T=7,I('L-"@D)?0T*
M"0EI;FQI;F4@=F]I9"!A<FTH*2![#0H)"0EM7U-T871U<R ](&%R;65D.PT*
M"0E]#0H)"6EN;&EN92!V;VED(&1I<V%R;2_at_I('L-"@D)"6U?4W1A='5S(#T@
M9&ES87)M960[#0H)"7T-"@D):6YL:6YE(&5N=6U38V]P94=U87)D4W1A='5S
M(&=E=%]S=&%T=7,H*2!C;VYS="![#0H)"0ER971U<FX@;5]3=&%T=7,[#0H)
M"7T-"@E].PT*#0I]("\O(&YA;65S<&%C92!D971A:6P-"@T*+R\A($1I<F5C
M="!F=6YC=&]R(&EN=F]K97(@8VQA<W,-"F-L87-S('-I;7!L95]I;G9O:V5R
M('L-"G!R;W1E8W1E9#H-"@ET96UP;&%T93P@='EP96YA;64_at_1G5N8W1O<E0@
M/@T*"6EN;&EN92!V;VED(&9I<F4H1G5N8W1O<E0_at_8V]N<W0F($9U;F-T;W(I
M(&-O;G-T('L-"@D)1G5N8W1O<B_at_[hidden]*"7T-"GT[#0H-"B\O(2!#;&%S<R!F
M;W(@96YU;65R871I;F<@97AC97!T:6]N('1Y<&5S#0IT96UP;&%T93P@='EP
M96YA;64_at_17AC97!T:6]N5# @7U]30T]015]'54%21%]%3E5-15)!5$5?34%#
M4D]?*%]?4T-/4$5?1U5!4D1?5$5-4$Q!5$5?4$%204U3*2 ^#0IS=')U8W0@
M97AC97!T:6]N<PT*>PT*"5]?4T-/4$5?1U5!4D1?14Y53452051%7TU!0U)/
M*%]?4T-/4$5?1U5!4D1?5%E0141%1E,I#0I].PT*#0HO+R$@17AC97!T:6]N
M(&-A=&-H:6YG(&9U;F-T;W(@:6YV;VME<B!C;&%S<PT*=&5M<&QA=&4\(&-L
M87-S($5(86YD;&5R5"P_at_8VQA<W,@17AC97!T:6]N<TQI<W14+"!T>7!E;F%M
M92!%2&%N9&QE<E!T<E0@/2!%2&%N9&QE<E0J(#X-"F-L87-S('=I=&A?8V%T
M8VAE<B Z('!U8FQI8R!%>&-E<'1I;VYS3&ES=%0-"GL-"G!U8FQI8SH-"@ET
M>7!E9&5F($5(86YD;&5R5"!E>&-E<'1I;VYS7VAA;F1L97)?='EP93L-"@ET
M>7!E9&5F($5(86YD;&5R4'1R5"!E>&-E<'1I;VYS7VAA;F1L97)?<&]I;G1E
M<E]T>7!E.PT*#0IP<F]T96-T960Z#0H)97AC97!T:6]N<U]H86YD;&5R7W!O
M:6YT97)?='EP92!M7W!(86YD;&5R.PT*#0IP=6)L:6,Z#0H)=VET:%]C871C
M:&5R*"D_at_.B!M7W!(86YD;&5R*"D@>PT*"7T-"@EW:71H7V-A=&-H97(H='EP
M96YA;64_at_9&5T86EL.CIP;VEN=&5R7W1Y<&4\(&5X8V5P=&EO;G-?:&%N9&QE
M<E]P;VEN=&5R7W1Y<&4@/CHZ='EP92!P2&%N9&QE<BD_at_.B!M7W!(86YD;&5R
M*'!(86YD;&5R*2![#0H)?0T*#0IP<F]T96-T960Z#0H)=&5M<&QA=&4\('1Y
M<&5N86UE($9U;F-T;W)4(#X-"@EI;FQI;F4@=F]I9"!F:7)E*$9U;F-T;W)4
M(&-O;G-T)B!&=6YC=&]R*2!C;VYS="![#0H)"71R>2![#0H)"0E&=6YC=&]R
M*"D[#0H)"7T_at_7U]30T]015]'54%21%]%3E5-15)!5$5?34%#4D\H7U]30T]0
M15]'54%21%]#051#2$53*3L-"@E]#0I].PT*#0I]("\O(&YA;65S<&%C92!G
M=6%R9 T*#0HO+R$@1&5S=')U8W1I;F<@<V-O<&4_at_9W5A<F0_at_8VQA<W,-"G1E
M;7!L871E/"!C;&%S<R!);G9O:V5R5" ](&=U87)D.CIS:6UP;&5?:6YV;VME
M<B ^#0IC;&%S<R!L96%V:6YG7W-C;W!E7V=U87)D(#H-"@EP<FEV871E(&YO
M;F-O<'EA8FQE+ T*"7!U8FQI8R!G=6%R9#HZ9&5T86EL.CIS8V]P95]G=6%R
M9%]T<FEG9V5R+ T*"7!U8FQI8R!);G9O:V5R5 T*>PT*<')O=&5C=&5D._at_T*
M"71Y<&5D968_at_9W5A<F0Z.F1E=&%I;#HZ<V-O<&5?9W5A<F1?=')I9V=E<B!T
M<FEG9V5R7W1Y<&4[#0H-"G!U8FQI8SH-"@ET>7!E9&5F($EN=F]K97)4(&EN
M=F]K97)?='EP93L-"@ET>7!E9&5F(&9U;F-T:6]N,#P@=F]I9" ^(&9U;F-T
M;W)?='EP93L-"@T*<')O=&5C=&5D._at_T*"69U;F-T;W)?='EP92!M7TQE879I
M;F=&=6YC=&]R.PT*#0IP<FEV871E._at_T*"6QE879I;F=?<V-O<&5?9W5A<F0H
M*3L-"@T*<'5B;&EC._at_T*"6QE879I;F=?<V-O<&5?9W5A<F0H9G5N8W1O<E]T
M>7!E(&-O;G-T)B!,96%V:6YG1G5N8W1O<BP@:6YV;VME<E]T>7!E(&-O;G-T
M)B!);G9O:V5R(#T@:6YV;VME<E]T>7!E*"DL(&=U87)D.CIE;G5M4V-O<&5'
M=6%R9%-T871U<R!3=&%T=7,@/2!G=6%R9#HZ87)M960I#0H)"3H@=')I9V=E
M<E]T>7!E*%-T871U<RDL(&EN=F]K97)?='EP92A);G9O:V5R*2P@;5],96%V
M:6YG1G5N8W1O<BA,96%V:6YG1G5N8W1O<BD-"@E[#0H)?0T*"6QE879I;F=?
M<V-O<&5?9W5A<F0H9G5N8W1O<E]T>7!E(&-O;G-T)B!,96%V:6YG1G5N8W1O
M<BP_at_9W5A<F0Z.F5N=6U38V]P94=U87)D4W1A='5S(%-T871U<RP@:6YV;VME
M<E]T>7!E(&-O;G-T)B!);G9O:V5R(#T@:6YV;VME<E]T>7!E*"DI#0H)"3H@
M=')I9V=E<E]T>7!E*%-T871U<RDL(&EN=F]K97)?='EP92A);G9O:V5R*2P@
M;5],96%V:6YG1G5N8W1O<BA,96%V:6YG1G5N8W1O<BD-"@E[#0H)?0T*"7YL
M96%V:6YG7W-C;W!E7V=U87)D*"D@>PT*"0EI9B H*"AC:&%R*71R:6=G97)?
M='EP93HZ9V5T7W-T871U<R_at_I('P@*&-H87(I=&AI<RT^;5],96%V:6YG1G5N
M8W1O<BYE;7!T>2_at_I*2 ]/2 P*0T*"0D)=&AI<RT^9FER95]L96%V:6YG7V9U
M;B_at_[hidden]*"7T-"@DO+R$@5&AE(&UE=&AO9"!E>'!L:6-I=&QY(&-A;&QS('1H
M92!L96%V:6YG(&9U;F-T;W(-"@EI;FQI;F4@=F]I9"!F:7)E7VQE879I;F=?
M9G5N*"D_at_8V]N<W0@>PT*"0EI;G9O:V5R7W1Y<&4Z.F9I<F4H=&AI<RT^;5],
M96%V:6YG1G5N8W1O<BD[#0H)?0T*"2\O(2!4:&4@;65T:&]D(')E9&5F:6YE
M<R!T:&4@;&5A=FEN9R!F=6YC=&]R#0H):6YL:6YE('9O:60_at_87-S:6=N7VQE
M879I;F=?9G5N*&9U;F-T;W)?='EP92!C;VYS="8_at_1G5N8W1O<BD@>PT*"0ET
M:&ES+3YM7TQE879I;F=&=6YC=&]R(#T_at_1G5N8W1O<CL-"@E]#0I].PT*#0HO
M+R$@0V]N<W1R=6-T:6YG(&%N9"!D97-T<G5C=&EN9R!S8V]P92!G=6%R9"!C
M;&%S<PT*=&5M<&QA=&4\(&-L87-S($EN=F]K97)4(#T_at_9W5A<F0Z.G-I;7!L
M95]I;G9O:V5R(#X-"F-L87-S('-C;W!E7V=U87)D(#H@<'5B;&EC(&QE879I
M;F=?<V-O<&5?9W5A<F0\($EN=F]K97)4(#X-"GL-"G!R:79A=&4Z#0H)='EP
M961E9B!L96%V:6YG7W-C;W!E7V=U87)D/"!);G9O:V5R5" ^(&)A<V5?='EP
M93L-"@T*<')O=&5C=&5D._at_T*"71Y<&5D968@='EP96YA;64_at_8F%S95]T>7!E
M.CIT<FEG9V5R7W1Y<&4@=')I9V=E<E]T>7!E.PT*#0IP=6)L:6,Z#0H)='EP
M961E9B!T>7!E;F%M92!B87-E7W1Y<&4Z.FEN=F]K97)?='EP92!I;G9O:V5R
M7W1Y<&4[#0H)='EP961E9B!T>7!E;F%M92!B87-E7W1Y<&4Z.F9U;F-T;W)?
M='EP92!F=6YC=&]R7W1Y<&4[#0H-"G!R;W1E8W1E9#H-"@EF=6YC=&]R7W1Y
M<&4@;5]%;G1E<FEN9T9U;F-T;W([#0H-"G!R:79A=&4Z#0H)<V-O<&5?9W5A
M<F0H*3L-"@T*<'5B;&EC._at_T*"7-C;W!E7V=U87)D* T*"0EF=6YC=&]R7W1Y
M<&4_at_8V]N<W0F($5N=&5R:6YG1G5N8W1O<BP-"@D)9G5N8W1O<E]T>7!E(&-O
M;G-T)B!,96%V:6YG1G5N8W1O<BP-"@D):6YV;VME<E]T>7!E(&-O;G-T)B!)
M;G9O:V5R(#T@:6YV;VME<E]T>7!E*"DL#0H)"6=U87)D.CIE;G5M4V-O<&5'
M=6%R9%-T871U<R!3=&%T=7,@/2!G=6%R9#HZ87)M960-"@DI(#H_at_8F%S95]T
M>7!E*$QE879I;F=&=6YC=&]R+"!);G9O:V5R+"!3=&%T=7,I+"!M7T5N=&5R
M:6YG1G5N8W1O<BA%;G1E<FEN9T9U;F-T;W(I#0H)>PT*"0EI9B H*"AC:&%R
M*71R:6=G97)?='EP93HZ9V5T7W-T871U<R_at_I('P@*&-H87(I=&AI<RT^;5]%
M;G1E<FEN9T9U;F-T;W(N96UP='DH*2D@/3T@,"D-"@D)"71H:7,M/F9I<F5?
M96YT97)I;F=?9G5N*"D[#0H)?0T*"7-C;W!E7V=U87)D* T*"0EF=6YC=&]R
M7W1Y<&4_at_8V]N<W0F($5N=&5R:6YG1G5N8W1O<BP-"@D)9G5N8W1O<E]T>7!E
M(&-O;G-T)B!,96%V:6YG1G5N8W1O<BP-"@D)9W5A<F0Z.F5N=6U38V]P94=U
M87)D4W1A='5S(%-T871U<RP-"@D):6YV;VME<E]T>7!E(&-O;G-T)B!);G9O
M:V5R(#T@:6YV;VME<E]T>7!E*"D-"@DI(#H_at_8F%S95]T>7!E*$QE879I;F=&
M=6YC=&]R+"!);G9O:V5R+"!3=&%T=7,I+"!M7T5N=&5R:6YG1G5N8W1O<BA%
M;G1E<FEN9T9U;F-T;W(I#0H)>PT*"0EI9B H*"AC:&%R*71R:6=G97)?='EP
M93HZ9V5T7W-T871U<R_at_I('P@*&-H87(I=&AI<RT^;5]%;G1E<FEN9T9U;F-T
M;W(N96UP='DH*2D@/3T@,"D-"@D)"71H:7,M/F9I<F5?96YT97)I;F=?9G5N
M*"D[#0H)?0T*"2\O(2!4:&4@;65T:&]D(&5X<&QI8VET;'D_at_8V%L;',@=&AE
M(&5N=&5R:6YG(&9U;F-T;W(-"@EI;FQI;F4@=F]I9"!F:7)E7V5N=&5R:6YG
M7V9U;B_at_I(&-O;G-T('L-"@D):6YV;VME<E]T>7!E.CIF:7)E*'1H:7,M/FU?
M16YT97)I;F=&=6YC=&]R*3L-"@E]#0H)+R\A(%1H92!M971H;V0@<F5D969I
M;F5S('1H92!E;G1E<FEN9R!F=6YC=&]R#0H):6YL:6YE('9O:60_at_87-S:6=N
M7V5N=&5R:6YG7V9U;BAF=6YC=&]R7W1Y<&4_at_8V]N<W0F($9U;F-T;W(I('L-
M"@D)=&AI<RT^;5]%;G1E<FEN9T9U;F-T;W(@/2!&=6YC=&]R.PT*"7T-"GT[
M#0H-"GT@+R\@;F%M97-P86-E(&)O;W-T#0H-"@T*+R\@36%C<F]S97,@9F]R
M('-E='1I;F<@=7 @86YO;GEM;W5S('-C;W!E(&=U87)D<PT*#0HC9&5F:6YE
M(%]?4T-/4$5?1U5!4D1?3D%-15\H<')E9FEX+"!P;W-T9FEX*2!P<F5F:7_at_C
M(W!O<W1F:7_at_-"B-D969I;F4_at_7U]30T]015]'54%21%].04U%*'!R969I>"P@
M<&]S=&9I>"D_at_7U]30T]015]'54%21%].04U%7RAP<F5F:7_at_L('!O<W1F:7_at_I
M#0H-"B\O($EN(%9#('=H96X_at_8V]M<&EL:6YG('=I=&@@+UI)(&]P=&EO;B!?
M7TQ)3D5?7R!M86-R;R!I<R!C;W)R=7!T960-"B-I9B!D969I;F5D*%]-4T-?
M5D52*2 F)B!?35-#7U9%4B ^/2 Q,S P#0H-"B-D969I;F4_at_3$5!5DE.1U]3
M0T]015]'54%21"AF=6YC=&]R*2!<#0H)8F]O<W0Z.FQE879I;F=?<V-O<&5?
M9W5A<F0\(#X_at_7U]30T]015]'54%21%].04U%*%]G=6%R9%\L(%]?0T]53E1%
M4E]?*2 H9G5N8W1O<BD[#0HC9&5F:6YE($Q%059)3D=?4T-/4$5?1U5!4D1?
M15_at_H9G5N8W1O<BP_at_97AC7W1Y<&5?;&ES="P_at_97AC7VEF86-E+"!H86YD;&5R
M*2!<#0H)8F]O<W0Z.FQE879I;F=?<V-O<&5?9W5A<F0\(&)O;W-T.CIG=6%R
M9#HZ=VET:%]C871C:&5R/"!E>&-?:69A8V4L(&)O;W-T.CIG=6%R9#HZ97AC
M97!T:6]N<SP_at_97AC7W1Y<&5?;&ES=" ^(#X@/B!?7U-#3U!%7T=505)$7TY!
M344H7V=U87)D7V5X7RP_at_7U]#3U5.5$527U\I("AF=6YC=&]R+"!H86YD;&5R
M*3L-"@T*(V1E9FEN92!30T]015]'54%21"AE;G1E<E]F=6YC=&]R+"!L96%V
M95]F=6YC=&]R*2!<#0H)8F]O<W0Z.G-C;W!E7V=U87)D/" ^(%]?4T-/4$5?
M1U5!4D1?3D%-12A?9W5A<F1?+"!?7T-/54Y415)?7RD@*&5N=&5R7V9U;F-T
M;W(L(&QE879E7V9U;F-T;W(I.PT*(V1E9FEN92!30T]015]'54%21%]%6"AE
M;G1E<E]F=6YC=&]R+"!L96%V95]F=6YC=&]R+"!E>&-?='EP95]L:7-T+"!E
M>&-?:69A8V4L(&AA;F1L97(I(%P-"@EB;V]S=#HZ;&5A=FEN9U]S8V]P95]G
M=6%R9#P_at_8F]O<W0Z.F=U87)D.CIW:71H7V-A=&-H97(\(&5X8U]I9F%C92P@
M8F]O<W0Z.F=U87)D.CIE>&-E<'1I;VYS/"!E>&-?='EP95]L:7-T(#X@/B ^
M(%]?4T-/4$5?1U5!4D1?3D%-12A?9W5A<F1?97A?+"!?7T-/54Y415)?7RD@
M*&5N=&5R7V9U;F-T;W(L(&QE879E7V9U;F-T;W(L(&AA;F1L97(I.PT*#0HC
M96QS90T*#0HC9&5F:6YE($Q%059)3D=?4T-/4$5?1U5!4D0H9G5N8W1O<BD@
M7 T*"6)O;W-T.CIL96%V:6YG7W-C;W!E7V=U87)D/" ^(%]?4T-/4$5?1U5!
M4D1?3D%-12A?9W5A<F1?+"!?7TQ)3D5?7RD@*&9U;F-T;W(I.PT*(V1E9FEN
M92!,14%624Y'7U-#3U!%7T=505)$7T58*&9U;F-T;W(L(&5X8U]T>7!E7VQI
M<W0L(&5X8U]I9F%C92P@:&%N9&QE<BD_at_7 T*"6)O;W-T.CIL96%V:6YG7W-C
M;W!E7V=U87)D/"!B;V]S=#HZ9W5A<F0Z.G=I=&A?8V%T8VAE<CP_at_97AC7VEF
M86-E+"!B;V]S=#HZ9W5A<F0Z.F5X8V5P=&EO;G,\(&5X8U]T>7!E7VQI<W0@
M/B ^(#X_at_7U]30T]015]'54%21%].04U%*%]G=6%R9%]E>%\L(%]?3$E.15]?
M*2 H9G5N8W1O<BP@:&%N9&QE<BD[#0H-"B-D969I;F4_at_4T-/4$5?1U5!4D0H
M96YT97)?9G5N8W1O<BP@;&5A=F5?9G5N8W1O<BD_at_7 T*"6)O;W-T.CIS8V]P
M95]G=6%R9#P@/B!?7U-#3U!%7T=505)$7TY!344H7V=U87)D7RP_at_7U],24Y%
M7U\I("AE;G1E<E]F=6YC=&]R+"!L96%V95]F=6YC=&]R*3L-"B-D969I;F4@
M4T-/4$5?1U5!4D1?15_at_H96YT97)?9G5N8W1O<BP@;&5A=F5?9G5N8W1O<BP@
M97AC7W1Y<&5?;&ES="P_at_97AC7VEF86-E+"!H86YD;&5R*2!<#0H)8F]O<W0Z
M.FQE879I;F=?<V-O<&5?9W5A<F0\(&)O;W-T.CIG=6%R9#HZ=VET:%]C871C
M:&5R/"!E>&-?:69A8V4L(&)O;W-T.CIG=6%R9#HZ97AC97!T:6]N<SP_at_97AC
M7W1Y<&5?;&ES=" ^(#X@/B!?7U-#3U!%7T=505)$7TY!344H7V=U87)D7V5X
M7RP_at_7U],24Y%7U\I("AE;G1E<E]F=6YC=&]R+"!L96%V95]F=6YC=&]R+"!H
M86YD;&5R*3L-"@T*(V5N9&EF("\O(&1E9FEN960H7TU30U]615(I("8F(%]-
M4T-?5D52(#X](#$S,# -"@T*(V1E9FEN92!30T]015]'54%21%]%6$-%4%1)
M3TY37S$H97AC97!T:6]N7W1Y<&4P*2!E>&-E<'1I;VY?='EP93 -"B-D969I
M;F4_at_4T-/4$5?1U5!4D1?15A#15!424].4U\R*&5X8V5P=&EO;E]T>7!E,"P@
M97AC97!T:6]N7W1Y<&4Q*5P-"@E30T]015]'54%21%]%6$-%4%1)3TY37S$H
M97AC97!T:6]N7W1Y<&4P*2P_at_97AC97!T:6]N7W1Y<&4Q#0HC9&5F:6YE(%-#
M3U!%7T=505)$7T580T505$E/3E-?,RAE>&-E<'1I;VY?='EP93 L(&5X8V5P
M=&EO;E]T>7!E,2P_at_97AC97!T:6]N7W1Y<&4R*5P-"@E30T]015]'54%21%]%
M6$-%4%1)3TY37S(H97AC97!T:6]N7W1Y<&4P+"!E>&-E<'1I;VY?='EP93$I
M+"!E>&-E<'1I;VY?='EP93(-"B-D969I;F4_at_4T-/4$5?1U5!4D1?15A#15!4
M24].4U\T*&5X8V5P=&EO;E]T>7!E,"P_at_97AC97!T:6]N7W1Y<&4Q+"!E>&-E
M<'1I;VY?='EP93(L(&5X8V5P=&EO;E]T>7!E,RE<#0H)4T-/4$5?1U5!4D1?
M15A#15!424].4U\S*&5X8V5P=&EO;E]T>7!E,"P_at_97AC97!T:6]N7W1Y<&4Q
M+"!E>&-E<'1I;VY?='EP93(I+"!E>&-E<'1I;VY?='EP93,-"B-D969I;F4@
M4T-/4$5?1U5!4D1?15A#15!424].4U\U*&5X8V5P=&EO;E]T>7!E,"P_at_97AC
M97!T:6]N7W1Y<&4Q+"!E>&-E<'1I;VY?='EP93(L(&5X8V5P=&EO;E]T>7!E
M,RP_at_97AC97!T:6]N7W1Y<&4T*5P-"@E30T]015]'54%21%]%6$-%4%1)3TY3
M7S0H97AC97!T:6]N7W1Y<&4P+"!E>&-E<'1I;VY?='EP93$L(&5X8V5P=&EO
M;E]T>7!E,BP_at_97AC97!T:6]N7W1Y<&4S*2P_at_97AC97!T:6]N7W1Y<&4T#0HC
M9&5F:6YE(%-#3U!%7T=505)$7T580T505$E/3E-?-BAE>&-E<'1I;VY?='EP
M93 L(&5X8V5P=&EO;E]T>7!E,2P_at_97AC97!T:6]N7W1Y<&4R+"!E>&-E<'1I
M;VY?='EP93,L(&5X8V5P=&EO;E]T>7!E-"P_at_97AC97!T:6]N7W1Y<&4U*5P-
M"@E30T]015]'54%21%]%6$-%4%1)3TY37S4H97AC97!T:6]N7W1Y<&4P+"!E
M>&-E<'1I;VY?='EP93$L(&5X8V5P=&EO;E]T>7!E,BP_at_97AC97!T:6]N7W1Y
M<&4S+"!E>&-E<'1I;VY?='EP930I+"!E>&-E<'1I;VY?='EP934-"B-D969I
M;F4_at_4T-/4$5?1U5!4D1?15A#15!424].4U\W*&5X8V5P=&EO;E]T>7!E,"P@
M97AC97!T:6]N7W1Y<&4Q+"!E>&-E<'1I;VY?='EP93(L(&5X8V5P=&EO;E]T
M>7!E,RP_at_97AC97!T:6]N7W1Y<&4T+"!E>&-E<'1I;VY?='EP934L(&5X8V5P
M=&EO;E]T>7!E-BE<#0H)4T-/4$5?1U5!4D1?15A#15!424].4U\V*&5X8V5P
M=&EO;E]T>7!E,"P_at_97AC97!T:6]N7W1Y<&4Q+"!E>&-E<'1I;VY?='EP93(L
M(&5X8V5P=&EO;E]T>7!E,RP_at_97AC97!T:6]N7W1Y<&4T+"!E>&-E<'1I;VY?
M='EP934I+"!E>&-E<'1I;VY?='EP938-"B-D969I;F4_at_4T-/4$5?1U5!4D1?
M15A#15!424].4U\X*&5X8V5P=&EO;E]T>7!E,"P_at_97AC97!T:6]N7W1Y<&4Q
M+"!E>&-E<'1I;VY?='EP93(L(&5X8V5P=&EO;E]T>7!E,RP_at_97AC97!T:6]N
M7W1Y<&4T+"!E>&-E<'1I;VY?='EP934L(&5X8V5P=&EO;E]T>7!E-BP_at_97AC
M97!T:6]N7W1Y<&4W*5P-"@E30T]015]'54%21%]%6$-%4%1)3TY37S<H97AC
M97!T:6]N7W1Y<&4P+"!E>&-E<'1I;VY?='EP93$L(&5X8V5P=&EO;E]T>7!E
M,BP_at_97AC97!T:6]N7W1Y<&4S+"!E>&-E<'1I;VY?='EP930L(&5X8V5P=&EO
M;E]T>7!E-2P_at_97AC97!T:6]N7W1Y<&4V*2P_at_97AC97!T:6]N7W1Y<&4W#0HC
M9&5F:6YE(%-#3U!%7T=505)$7T580T505$E/3E-?.2AE>&-E<'1I;VY?='EP
M93 L(&5X8V5P=&EO;E]T>7!E,2P_at_97AC97!T:6]N7W1Y<&4R+"!E>&-E<'1I
M;VY?='EP93,L(&5X8V5P=&EO;E]T>7!E-"P_at_97AC97!T:6]N7W1Y<&4U+"!E
M>&-E<'1I;VY?='EP938L(&5X8V5P=&EO;E]T>7!E-RP_at_97AC97!T:6]N7W1Y
M<&4X*5P-"@E30T]015]'54%21%]%6$-%4%1)3TY37S_at_H97AC97!T:6]N7W1Y
M<&4P+"!E>&-E<'1I;VY?='EP93$L(&5X8V5P=&EO;E]T>7!E,BP_at_97AC97!T
M:6]N7W1Y<&4S+"!E>&-E<'1I;VY?='EP930L(&5X8V5P=&EO;E]T>7!E-2P@
M97AC97!T:6]N7W1Y<&4V+"!E>&-E<'1I;VY?='EP93<I+"!E>&-E<'1I;VY?
M='EP93_at_-"B-D969I;F4_at_4T-/4$5?1U5!4D1?15A#15!424].4U\Q,"AE>&-E
M<'1I;VY?='EP93 L(&5X8V5P=&EO;E]T>7!E,2P_at_97AC97!T:6]N7W1Y<&4R
M+"!E>&-E<'1I;VY?='EP93,L(&5X8V5P=&EO;E]T>7!E-"P_at_97AC97!T:6]N
M7W1Y<&4U+"!E>&-E<'1I;VY?='EP938L(&5X8V5P=&EO;E]T>7!E-RP_at_97AC
M97!T:6]N7W1Y<&4X+"!E>&-E<'1I;VY?='EP93DI7 T*"5-#3U!%7T=505)$
M7T580T505$E/3E-?.2AE>&-E<'1I;VY?='EP93 L(&5X8V5P=&EO;E]T>7!E
M,2P_at_97AC97!T:6]N7W1Y<&4R+"!E>&-E<'1I;VY?='EP93,L(&5X8V5P=&EO
M;E]T>7!E-"P_at_97AC97!T:6]N7W1Y<&4U+"!E>&-E<'1I;VY?='EP938L(&5X
M8V5P=&EO;E]T>7!E-RP_at_97AC97!T:6]N7W1Y<&4X*2P_at_97AC97!T:6]N7W1Y
M<&4Y#0H-"B\O($-L96%N:6YG('5P(&UA8W)O<V5S#0HC=6YD968_at_7U]30T]0
M15]'54%21%]#051#2$53#0HC=6YD968_at_7U]30T]015]'54%21%]465!%1$5&
M4PT*(W5N9&5F(%]?4T-/4$5?1U5!4D1?5$5-4$Q!5$5?4$%204U3#0HC=6YD
M968_at_7U]30T]015]'54%21%].54Q,5%E015,-"B-U;F1E9B!?7U-#3U!%7T=5
M05)$7T5.54U%4D%415]-04-23PT*(W5N9&5F(%]?4T-/4$5?1U5!4D1?14Y5
M3452051%7TU!0U)/7PT*#0HC96YD:68@+R\@7U]30T]014=505)$7TA?7PT*
`
end


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk