Boost logo

Boost :

Subject: [boost] safe bool operator
From: Domagoj Saric (domagoj.saric_at_[hidden])
Date: 2010-03-01 15:36:28


While examining source and binary code for the various
safe_bool/unspecified_bool_type implementations two issues can be noticed:
 - source code verbosity/repetition
 - binary code inefficiency

The first issue is made worse by the fact that even this simple idiom is broken
on some compilers ('pointed out' by workarounds in
smart_ptr/detail/operator_bool.hpp) so workarounds must also be
copied/'rediscovered'...

The second issue (related to the usual implementation with member function
pointers) has two sides, one is that taking the address of a function will force
it to be included in the resulting binary even if it is never used or is always
inlined and the second is that some compilers produce non-optimal code. For
example for the following source code:

boost::optional<int> test1;
boost::optional<int> test2;

__declspec( noinline )
void func()
{
    if ( test1 )
        test2 = *test1;
}

MSVC++ 8.0 and 9.0 will produce the following binary code
...
0F923A26 movzx eax,byte ptr [test1 (0F968210h)]
0F923A2D neg eax
0F923A2F sbb eax,eax
0F923A31 test eax,offset
boost::optional_detail::optional_base<int>::is_initialized (0F923B9Eh)
0F923A36 je ...
...

but if the if line is changed to if ( test1.is_initialized() ) the following
code will be produced:
...
0F923A26 cmp byte ptr [test1 (0F968210h)],0
0F923A2D je ...
...

At first I tried a solution that takes advantage of the fact that MSVC++ has
plain-pointer-sized/register-sized member function pointers for plain single
inheritance non virtual member functions and worked properly but than I
found old discussions about the same subject:
http://lists.boost.org/Archives/boost/2003/09/52846.php
http://lists.boost.org/Archives/boost/2002/10/38624.php
where the solution for MSVC++ was to use a pointer member data which gives the
same results as my initial solution...

Anyways I've attached a .hpp file with a draft implementation proposal (missing
the compiler workarounds from smart_ptr/smart_ptr/detail/operator_bool.hpp for
example) that uses both approaches...

It enables a one liner implementation for a safe_bool operator:

class my_class
{
public:
    bool some_is_valid_function() const;
    operator boost::unspecified_bool_type() const { return
          boost::make_safe_bool( some_is_valid_function() ); }

    //or by using a macro
    BOOST_SAFE_BOOL_FROM_FUNCTION( some_is_valid_function() )
}

--
"What Huxley teaches is that in the age of advanced technology, spiritual
devastation is more likely to come from an enemy with a smiling face than from
one whose countenance exudes suspicion and hate."
Neil Postman
begin 666 safe_bool.hpp
M(W!R86=M82!O;F-E#0HC:69N9&5F('-A9F5?8F]O;%]H<' -"B-D969I;F4@
M<V%F95]B;V]L7VAP< T*+R\M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2T-"B-I;F-L=61E(")M<&PO8F]O;"YH<' B#0HO+RTM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0T*;F%M97-P86-E(&)O;W-T#0I[#0HO
M+RTM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0T*#0IN86UE<W!A
M8V4_at_9&5T86EL#0I[#0H@(" @<W1R=6-T('5N<W!E8VEF:65D7V)O;VQ?='EP
M95]H96QP97(-"B @("![#0H@(" @(" @('9O:60@;65M8F5R7V9U;F-T:6]N
M*"D@>WT[#0H@(" @(" @(&EN="!M96UB97)?9&%T85\[#0H@(" @?3L-"@T*
M(" @('1Y<&5D968@=F]I9" H=6YS<&5C:69I961?8F]O;%]T>7!E7VAE;'!E
M<CHZ*G5N<W!E8VEF:65D7V)O;VQ?='EP95]F=6YC=&EO;BD@*"D[#0H@(" @
M='EP961E9B!I;G0@("!U;G-P96-I9FEE9%]B;V]L7W1Y<&5?:&5L<&5R.CHJ
M=6YS<&5C:69I961?8F]O;%]T>7!E7V1A=&$@(" @(" @(#L-"@T*(" @('5N
M:6]N(&9A<W1?<V%F95]B;V]L#0H@(" @>PT*(" @(" @("!U;G-I9VYE9"!L
M;VYG(" @(" @(" @(" @(" @(" @<&QA:6Y?<&]I;G1E<E]P;&%C96AO;&1E
M<CL-"B @(" @(" @=6YS<&5C:69I961?8F]O;%]T>7!E7V9U;F-T:6]N('!O
M:6YT97)?=&]?;65M8F5R(" @(" @(" [#0H@(" @?3L-"@T*(" @("\O(" @
M270@:7,@87-S=6UE9"!T:&%T(&EF('1H92!C;VUP:6QE<B!I<R!A8FQE('1O
M(&9I="!A('!L86EN+"!S:6YG;&4-"B @(" O+R!I;FAE<FET86YC92!M96UB
M97(@9G5N8W1I;VX@<&]I;G1E<B!I;G1O('-I>F5O9B@@=F]I9" J("D@=&AA
M="!I=',@;G5L; T*(" @("\O(&)I;F%R>2!R97!R97-E;G1A=&EO;B!I<R!I
M9&5N=&EC86P@=&\@82!P;&%I;B!N=6QL('9O:60@<&]I;G1E<B H86QL(&)I
M=',-"B @(" O+R!Z97)O960I+B!7:71H;W5T(&$@=V%Y('1O(&-H96-K('1H
M:7,@870_at_8V]M<&EL92!T:6UE('1H:7,@87-S97)T960_at_870-"B @(" O+R!R
M=6YT:6UE+@T*(" @("\O(" @5&AE(&%B;W9E(&YE960@;F]T(&AO;&0_at_9F]R
M(&1A=&$@;65M8F5R('!O:6YT97)S("AE+F<N($U35D,K*R!U<V5S("TQ#0H@
M(" @+R\@9F]R(&YU;&PM9&%T82!M96UB97(@<&]I;G1E<G,I+@T*(" @('1Y
M<&5D968@;7!L.CIB;V]L7SPH('-I>F5O9B@@9F%S=%]S869E7V)O;VP@*2 \
M/2!S:7IE;V8H('5N<VEG;F5D(&QO;F<@*2 I/B!C86Y?=7-E7V9A<W1?8F]O
M;%]H86-K.PT*#0H@(" @='EP961E9B!M<&PZ.FEF7PT*(" @(" @(" @(" @
M/ T*(" @(" @(" @(" @(" @(&-A;E]U<V5?9F%S=%]B;V]L7VAA8VLL#0H@
M(" @(" @(" @(" @(" @=6YS<&5C:69I961?8F]O;%]T>7!E7V9U;F-T:6]N
M+ T*(" @(" @(" @(" @(" @('5N<W!E8VEF:65D7V)O;VQ?='EP95]D871A
M#0H@(" @(" @(" @(" ^.CIT>7!E('5N<W!E8VEF:65D7V)O;VQ?='EP93L-
M"@T*(" @(&EN;&EN90T*(" @('5N<W!E8VEF:65D7V)O;VQ?='EP92!M86ME
M7W-A9F5?8F]O;%]W;W)K97(H(&)O;VP_at_8V]N<W0@=F%L=64L(&UP;#HZ=')U
M95\@+RIU<V4_at_9F%S="UH86-K('9E<G-I;VXJ+R I#0H@(" @>PT*(" @(" @
M("!F87-T7W-A9F5?8F]O;"!C;VYS="!F87-T4V%F94)O;VP@/2![('9A;'5E
M('T[#0H@(" @(" @(&%S<V5R= T*(" @(" @(" H#0H@(" @(" @(" @(" H
M("$A9F%S=%-A9F5";V]L+G!O:6YT97)?=&]?;65M8F5R(#T]("$A=F%L=64@
M*2 F)@T*(" @(" @(" @(" @(E1H92!V;VED+7!O:6YT97(M<VEZ960@;65M
M8F5R('!O:6YT97(@;G5L;"!B:6YA<GDB#0H@(" @(" @(" @(" B<F5P<F5S
M96YT871I;VX_at_87-S=6UP=&EO;B!D;V5S(&YO="!H;VQD(&9O<B!T:&ES(@T*
M(" @(" @(" @(" @(F-O;7!I;&5R+W!L871F;W)M+B(-"B @(" @(" @*3L-
M"B @(" @(" @<F5T=7)N(&9A<W13869E0F]O;"YP;VEN=&5R7W1O7VUE;6)E
M<CL-"B @("!]#0H-"B @("!I;FQI;F4-"B @("!U;G-P96-I9FEE9%]B;V]L
M7W1Y<&5?9G5N8W1I;VX-"B @("!M86ME7W-A9F5?8F]O;%]S=&%N9&%R9%]W
M;W)K97(H(&)O;VP_at_8V]N<W0_at_8F]O;%]V86QU92P@=6YS<&5C:69I961?8F]O
M;%]T>7!E7V9U;F-T:6]N(&-O;G-T(&YU;&Q?=F%L=64@*0T*(" @('L-"B @
M(" @(" @<F5T=7)N(&)O;VQ?=F%L=64@/R F=6YS<&5C:69I961?8F]O;%]T
M>7!E7VAE;'!E<CHZ;65M8F5R7V9U;F-T:6]N(#H@;G5L;%]V86QU93L-"B @
M("!]#0H@(" @:6YL:6YE#0H@(" @=6YS<&5C:69I961?8F]O;%]T>7!E7V1A
M=&$-"B @("!M86ME7W-A9F5?8F]O;%]S=&%N9&%R9%]W;W)K97(H(&)O;VP@
M8V]N<W0_at_8F]O;%]V86QU92P@=6YS<&5C:69I961?8F]O;%]T>7!E7V1A=&$@
M(" @(&-O;G-T(&YU;&Q?=F%L=64@*0T*(" @('L-"B @(" @(" @<F5T=7)N
M(&)O;VQ?=F%L=64@/R F=6YS<&5C:69I961?8F]O;%]T>7!E7VAE;'!E<CHZ
M;65M8F5R7V1A=&%?(" @(#H@;G5L;%]V86QU93L-"B @("!]#0H-"B @("!I
M;FQI;F4-"B @("!U;G-P96-I9FEE9%]B;V]L7W1Y<&4@;6%K95]S869E7V)O
M;VQ?=V]R:V5R*"!B;V]L(&-O;G-T('9A;'5E+"!M<&PZ.F9A;'-E7R O*G5S
M92!S=&%N9&%R9"!V97)S:6]N*B\@*0T*(" @('L-"B @(" @(" @<F5T=7)N
M(&UA:V5?<V%F95]B;V]L7W-T86YD87)D7W=O<FME<B@@=F%L=64L('5N<W!E
M8VEF:65D7V)O;VQ?='EP92@@," I("D[#0H@(" @?0T*?2 O+R!N86UE<W!A
M8V4_at_9&5T86EL#0H-"@T*='EP961E9B!D971A:6PZ.G5N<W!E8VEF:65D7V)O
M;VQ?='EP92!U;G-P96-I9FEE9%]B;V]L7W1Y<&4[#0H-"@T*:6YL:6YE#0IU
M;G-P96-I9FEE9%]B;V]L7W1Y<&4@;6%K95]S869E7V)O;VPH(&)O;VP_at_8V]N
M<W0@=F%L=64@*0T*>PT*(" @(')E='5R;B!D971A:6PZ.FUA:V5?<V%F95]B
M;V]L7W=O<FME<B@@=F%L=64L(&1E=&%I;#HZ8V%N7W5S95]F87-T7V)O;VQ?
M:&%C:R_at_I("D[#0I]#0H-"B\O($EF('=E(&-O=6QD('5S92!M96UB97(@<&]I
M;G1E<G,@8F5F;W)E('1H92!M96UB97(@:7,@86-T=6%L;'D_at_9&5C;&%R960O
M<V5E;@T*+R\@=V4_at_8V]U;&0@=7-E($-25% M8F%S960@:&5L<&5R(&-L87-S
M97,@9F]R(&UI;FEM=6T@=F5R8F]S:71Y('-A9F5?8F]O; T*+R\@:6UP;&5M
M96YT871I;VYS._at_T*+R\@=&5M<&QA=&4@/&-L87-S($)A<V4L(&)O;VP@*$)A
M<V4Z.BIB;V]L7V9U;F-T:6]N*2 H*2!C;VYS=#X-"B\O(&-L87-S('-A9F5?
M8F]O; T*+R\@>PT*+R\@(" @(&]P97)A=&]R('5N<W!E8VEF:65D7V)O;VQ?
M='EP92_at_I(&-O;G-T('L@<F5T=7)N(&UA:V5?<V%F95]B;V]L*"!S=&%T:6-?
M8V%S=#Q"87-E(&-O;G-T("H^*"!T:&ES("DM/BIB;V]L7V9U;F-T:6]N*"D@
M*3L@?0T*+R\@?3L-"B\O#0HO+R!C;&%S<R!M>5]C;&%S<R Z('!U8FQI8R!S
M869E7V)O;VP\;7E?8VQA<W,L("9M>5]C;&%S<SHZ=F%L:60^#0HO+RXN+@T*
M#0HO+RXN+FEN<W1E860@=V4_at_87)E(&QE9G0@=VET:"!M86-R;W,N+BX-"B-D
M969I;F4_at_0D]/4U1?4T%&15]"3T],7T923TU?1E5.0U1)3TXH(&-O;G-T365M
M8F5R1G5N8W1I;VX@*2!<#0H@(" @;W!E<F%T;W(@8F]O<W0Z.G5N<W!E8VEF
M:65D7V)O;VQ?='EP92_at_I(&-O;G-T('L@<F5T=7)N(&)O;W-T.CIM86ME7W-A
M9F5?8F]O;"@@8V]N<W1-96UB97)&=6YC=&EO;B_at_I("D[('T-"@T*(V1E9FEN
M92!"3T]35%]3049%7T)/3TQ?1E)/35]$051!*" @(" @8V]N<W1-96UB97)$
M871A(" @(" I(%P-"B @("!O<&5R871O<B!B;V]S=#HZ=6YS<&5C:69I961?
M8F]O;%]T>7!E*"D_at_8V]N<W0@>R!R971U<FX_at_8F]O<W0Z.FUA:V5?<V%F95]B
M;V]L*"!C;VYS=$UE;6)E<D1A=&$@(" @(" @*3L@?0T*#0H-"B\O+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM#0I]("\O(&YA;65S<&%C92!B
M;V]S= T*+R\M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T-"B-E
7;F1I9B O+R!S869E7V)O;VQ?:'!P#0H`
`
end

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