Ticket #4720: djw_unsafe_function.patch

File djw_unsafe_function.patch, 36.4 KB (added by Daniel Walker, 12 years ago)

Implements boost::unsafe_function with tests and docs.

  • boost/function/detail/gen_maybe_include.pl

     
    2929    print OUT " BOOST_FUNCTION_NUM_ARGS == $on_arg\n";
    3030    print OUT "#  ifndef BOOST_FUNCTION_$on_arg\n";
    3131    print OUT "#    define BOOST_FUNCTION_$on_arg\n";
     32    print OUT "#    define BOOST_FUNCTION_BE_SAFE\n";
    3233    print OUT "#    include <boost/function/function_template.hpp>\n";
     34    print OUT "#    undef BOOST_FUNCTION_BE_SAFE\n";
     35    print OUT "#    include <boost/function/function_template.hpp>\n";
    3336    print OUT "#  endif\n";
    3437}
    3538print OUT "#else\n";
  • boost/function/detail/maybe_include.hpp

     
    1010#if BOOST_FUNCTION_NUM_ARGS == 0
    1111#  ifndef BOOST_FUNCTION_0
    1212#    define BOOST_FUNCTION_0
     13#    define BOOST_FUNCTION_BE_SAFE
    1314#    include <boost/function/function_template.hpp>
     15#    undef BOOST_FUNCTION_BE_SAFE
     16#    include <boost/function/function_template.hpp>
    1417#  endif
    1518#elif BOOST_FUNCTION_NUM_ARGS == 1
    1619#  ifndef BOOST_FUNCTION_1
    1720#    define BOOST_FUNCTION_1
     21#    define BOOST_FUNCTION_BE_SAFE
    1822#    include <boost/function/function_template.hpp>
     23#    undef BOOST_FUNCTION_BE_SAFE
     24#    include <boost/function/function_template.hpp>
    1925#  endif
    2026#elif BOOST_FUNCTION_NUM_ARGS == 2
    2127#  ifndef BOOST_FUNCTION_2
    2228#    define BOOST_FUNCTION_2
     29#    define BOOST_FUNCTION_BE_SAFE
    2330#    include <boost/function/function_template.hpp>
     31#    undef BOOST_FUNCTION_BE_SAFE
     32#    include <boost/function/function_template.hpp>
    2433#  endif
    2534#elif BOOST_FUNCTION_NUM_ARGS == 3
    2635#  ifndef BOOST_FUNCTION_3
    2736#    define BOOST_FUNCTION_3
     37#    define BOOST_FUNCTION_BE_SAFE
    2838#    include <boost/function/function_template.hpp>
     39#    undef BOOST_FUNCTION_BE_SAFE
     40#    include <boost/function/function_template.hpp>
    2941#  endif
    3042#elif BOOST_FUNCTION_NUM_ARGS == 4
    3143#  ifndef BOOST_FUNCTION_4
    3244#    define BOOST_FUNCTION_4
     45#    define BOOST_FUNCTION_BE_SAFE
    3346#    include <boost/function/function_template.hpp>
     47#    undef BOOST_FUNCTION_BE_SAFE
     48#    include <boost/function/function_template.hpp>
    3449#  endif
    3550#elif BOOST_FUNCTION_NUM_ARGS == 5
    3651#  ifndef BOOST_FUNCTION_5
    3752#    define BOOST_FUNCTION_5
     53#    define BOOST_FUNCTION_BE_SAFE
    3854#    include <boost/function/function_template.hpp>
     55#    undef BOOST_FUNCTION_BE_SAFE
     56#    include <boost/function/function_template.hpp>
    3957#  endif
    4058#elif BOOST_FUNCTION_NUM_ARGS == 6
    4159#  ifndef BOOST_FUNCTION_6
    4260#    define BOOST_FUNCTION_6
     61#    define BOOST_FUNCTION_BE_SAFE
    4362#    include <boost/function/function_template.hpp>
     63#    undef BOOST_FUNCTION_BE_SAFE
     64#    include <boost/function/function_template.hpp>
    4465#  endif
    4566#elif BOOST_FUNCTION_NUM_ARGS == 7
    4667#  ifndef BOOST_FUNCTION_7
    4768#    define BOOST_FUNCTION_7
     69#    define BOOST_FUNCTION_BE_SAFE
    4870#    include <boost/function/function_template.hpp>
     71#    undef BOOST_FUNCTION_BE_SAFE
     72#    include <boost/function/function_template.hpp>
    4973#  endif
    5074#elif BOOST_FUNCTION_NUM_ARGS == 8
    5175#  ifndef BOOST_FUNCTION_8
    5276#    define BOOST_FUNCTION_8
     77#    define BOOST_FUNCTION_BE_SAFE
    5378#    include <boost/function/function_template.hpp>
     79#    undef BOOST_FUNCTION_BE_SAFE
     80#    include <boost/function/function_template.hpp>
    5481#  endif
    5582#elif BOOST_FUNCTION_NUM_ARGS == 9
    5683#  ifndef BOOST_FUNCTION_9
    5784#    define BOOST_FUNCTION_9
     85#    define BOOST_FUNCTION_BE_SAFE
    5886#    include <boost/function/function_template.hpp>
     87#    undef BOOST_FUNCTION_BE_SAFE
     88#    include <boost/function/function_template.hpp>
    5989#  endif
    6090#elif BOOST_FUNCTION_NUM_ARGS == 10
    6191#  ifndef BOOST_FUNCTION_10
    6292#    define BOOST_FUNCTION_10
     93#    define BOOST_FUNCTION_BE_SAFE
    6394#    include <boost/function/function_template.hpp>
     95#    undef BOOST_FUNCTION_BE_SAFE
     96#    include <boost/function/function_template.hpp>
    6497#  endif
    6598#elif BOOST_FUNCTION_NUM_ARGS == 11
    6699#  ifndef BOOST_FUNCTION_11
    67100#    define BOOST_FUNCTION_11
     101#    define BOOST_FUNCTION_BE_SAFE
    68102#    include <boost/function/function_template.hpp>
     103#    undef BOOST_FUNCTION_BE_SAFE
     104#    include <boost/function/function_template.hpp>
    69105#  endif
    70106#elif BOOST_FUNCTION_NUM_ARGS == 12
    71107#  ifndef BOOST_FUNCTION_12
    72108#    define BOOST_FUNCTION_12
     109#    define BOOST_FUNCTION_BE_SAFE
    73110#    include <boost/function/function_template.hpp>
     111#    undef BOOST_FUNCTION_BE_SAFE
     112#    include <boost/function/function_template.hpp>
    74113#  endif
    75114#elif BOOST_FUNCTION_NUM_ARGS == 13
    76115#  ifndef BOOST_FUNCTION_13
    77116#    define BOOST_FUNCTION_13
     117#    define BOOST_FUNCTION_BE_SAFE
    78118#    include <boost/function/function_template.hpp>
     119#    undef BOOST_FUNCTION_BE_SAFE
     120#    include <boost/function/function_template.hpp>
    79121#  endif
    80122#elif BOOST_FUNCTION_NUM_ARGS == 14
    81123#  ifndef BOOST_FUNCTION_14
    82124#    define BOOST_FUNCTION_14
     125#    define BOOST_FUNCTION_BE_SAFE
    83126#    include <boost/function/function_template.hpp>
     127#    undef BOOST_FUNCTION_BE_SAFE
     128#    include <boost/function/function_template.hpp>
    84129#  endif
    85130#elif BOOST_FUNCTION_NUM_ARGS == 15
    86131#  ifndef BOOST_FUNCTION_15
    87132#    define BOOST_FUNCTION_15
     133#    define BOOST_FUNCTION_BE_SAFE
    88134#    include <boost/function/function_template.hpp>
     135#    undef BOOST_FUNCTION_BE_SAFE
     136#    include <boost/function/function_template.hpp>
    89137#  endif
    90138#elif BOOST_FUNCTION_NUM_ARGS == 16
    91139#  ifndef BOOST_FUNCTION_16
    92140#    define BOOST_FUNCTION_16
     141#    define BOOST_FUNCTION_BE_SAFE
    93142#    include <boost/function/function_template.hpp>
     143#    undef BOOST_FUNCTION_BE_SAFE
     144#    include <boost/function/function_template.hpp>
    94145#  endif
    95146#elif BOOST_FUNCTION_NUM_ARGS == 17
    96147#  ifndef BOOST_FUNCTION_17
    97148#    define BOOST_FUNCTION_17
     149#    define BOOST_FUNCTION_BE_SAFE
    98150#    include <boost/function/function_template.hpp>
     151#    undef BOOST_FUNCTION_BE_SAFE
     152#    include <boost/function/function_template.hpp>
    99153#  endif
    100154#elif BOOST_FUNCTION_NUM_ARGS == 18
    101155#  ifndef BOOST_FUNCTION_18
    102156#    define BOOST_FUNCTION_18
     157#    define BOOST_FUNCTION_BE_SAFE
    103158#    include <boost/function/function_template.hpp>
     159#    undef BOOST_FUNCTION_BE_SAFE
     160#    include <boost/function/function_template.hpp>
    104161#  endif
    105162#elif BOOST_FUNCTION_NUM_ARGS == 19
    106163#  ifndef BOOST_FUNCTION_19
    107164#    define BOOST_FUNCTION_19
     165#    define BOOST_FUNCTION_BE_SAFE
    108166#    include <boost/function/function_template.hpp>
     167#    undef BOOST_FUNCTION_BE_SAFE
     168#    include <boost/function/function_template.hpp>
    109169#  endif
    110170#elif BOOST_FUNCTION_NUM_ARGS == 20
    111171#  ifndef BOOST_FUNCTION_20
    112172#    define BOOST_FUNCTION_20
     173#    define BOOST_FUNCTION_BE_SAFE
    113174#    include <boost/function/function_template.hpp>
     175#    undef BOOST_FUNCTION_BE_SAFE
     176#    include <boost/function/function_template.hpp>
    114177#  endif
    115178#elif BOOST_FUNCTION_NUM_ARGS == 21
    116179#  ifndef BOOST_FUNCTION_21
    117180#    define BOOST_FUNCTION_21
     181#    define BOOST_FUNCTION_BE_SAFE
    118182#    include <boost/function/function_template.hpp>
     183#    undef BOOST_FUNCTION_BE_SAFE
     184#    include <boost/function/function_template.hpp>
    119185#  endif
    120186#elif BOOST_FUNCTION_NUM_ARGS == 22
    121187#  ifndef BOOST_FUNCTION_22
    122188#    define BOOST_FUNCTION_22
     189#    define BOOST_FUNCTION_BE_SAFE
    123190#    include <boost/function/function_template.hpp>
     191#    undef BOOST_FUNCTION_BE_SAFE
     192#    include <boost/function/function_template.hpp>
    124193#  endif
    125194#elif BOOST_FUNCTION_NUM_ARGS == 23
    126195#  ifndef BOOST_FUNCTION_23
    127196#    define BOOST_FUNCTION_23
     197#    define BOOST_FUNCTION_BE_SAFE
    128198#    include <boost/function/function_template.hpp>
     199#    undef BOOST_FUNCTION_BE_SAFE
     200#    include <boost/function/function_template.hpp>
    129201#  endif
    130202#elif BOOST_FUNCTION_NUM_ARGS == 24
    131203#  ifndef BOOST_FUNCTION_24
    132204#    define BOOST_FUNCTION_24
     205#    define BOOST_FUNCTION_BE_SAFE
    133206#    include <boost/function/function_template.hpp>
     207#    undef BOOST_FUNCTION_BE_SAFE
     208#    include <boost/function/function_template.hpp>
    134209#  endif
    135210#elif BOOST_FUNCTION_NUM_ARGS == 25
    136211#  ifndef BOOST_FUNCTION_25
    137212#    define BOOST_FUNCTION_25
     213#    define BOOST_FUNCTION_BE_SAFE
    138214#    include <boost/function/function_template.hpp>
     215#    undef BOOST_FUNCTION_BE_SAFE
     216#    include <boost/function/function_template.hpp>
    139217#  endif
    140218#elif BOOST_FUNCTION_NUM_ARGS == 26
    141219#  ifndef BOOST_FUNCTION_26
    142220#    define BOOST_FUNCTION_26
     221#    define BOOST_FUNCTION_BE_SAFE
    143222#    include <boost/function/function_template.hpp>
     223#    undef BOOST_FUNCTION_BE_SAFE
     224#    include <boost/function/function_template.hpp>
    144225#  endif
    145226#elif BOOST_FUNCTION_NUM_ARGS == 27
    146227#  ifndef BOOST_FUNCTION_27
    147228#    define BOOST_FUNCTION_27
     229#    define BOOST_FUNCTION_BE_SAFE
    148230#    include <boost/function/function_template.hpp>
     231#    undef BOOST_FUNCTION_BE_SAFE
     232#    include <boost/function/function_template.hpp>
    149233#  endif
    150234#elif BOOST_FUNCTION_NUM_ARGS == 28
    151235#  ifndef BOOST_FUNCTION_28
    152236#    define BOOST_FUNCTION_28
     237#    define BOOST_FUNCTION_BE_SAFE
    153238#    include <boost/function/function_template.hpp>
     239#    undef BOOST_FUNCTION_BE_SAFE
     240#    include <boost/function/function_template.hpp>
    154241#  endif
    155242#elif BOOST_FUNCTION_NUM_ARGS == 29
    156243#  ifndef BOOST_FUNCTION_29
    157244#    define BOOST_FUNCTION_29
     245#    define BOOST_FUNCTION_BE_SAFE
    158246#    include <boost/function/function_template.hpp>
     247#    undef BOOST_FUNCTION_BE_SAFE
     248#    include <boost/function/function_template.hpp>
    159249#  endif
    160250#elif BOOST_FUNCTION_NUM_ARGS == 30
    161251#  ifndef BOOST_FUNCTION_30
    162252#    define BOOST_FUNCTION_30
     253#    define BOOST_FUNCTION_BE_SAFE
    163254#    include <boost/function/function_template.hpp>
     255#    undef BOOST_FUNCTION_BE_SAFE
     256#    include <boost/function/function_template.hpp>
    164257#  endif
    165258#elif BOOST_FUNCTION_NUM_ARGS == 31
    166259#  ifndef BOOST_FUNCTION_31
    167260#    define BOOST_FUNCTION_31
     261#    define BOOST_FUNCTION_BE_SAFE
    168262#    include <boost/function/function_template.hpp>
     263#    undef BOOST_FUNCTION_BE_SAFE
     264#    include <boost/function/function_template.hpp>
    169265#  endif
    170266#elif BOOST_FUNCTION_NUM_ARGS == 32
    171267#  ifndef BOOST_FUNCTION_32
    172268#    define BOOST_FUNCTION_32
     269#    define BOOST_FUNCTION_BE_SAFE
    173270#    include <boost/function/function_template.hpp>
     271#    undef BOOST_FUNCTION_BE_SAFE
     272#    include <boost/function/function_template.hpp>
    174273#  endif
    175274#elif BOOST_FUNCTION_NUM_ARGS == 33
    176275#  ifndef BOOST_FUNCTION_33
    177276#    define BOOST_FUNCTION_33
     277#    define BOOST_FUNCTION_BE_SAFE
    178278#    include <boost/function/function_template.hpp>
     279#    undef BOOST_FUNCTION_BE_SAFE
     280#    include <boost/function/function_template.hpp>
    179281#  endif
    180282#elif BOOST_FUNCTION_NUM_ARGS == 34
    181283#  ifndef BOOST_FUNCTION_34
    182284#    define BOOST_FUNCTION_34
     285#    define BOOST_FUNCTION_BE_SAFE
    183286#    include <boost/function/function_template.hpp>
     287#    undef BOOST_FUNCTION_BE_SAFE
     288#    include <boost/function/function_template.hpp>
    184289#  endif
    185290#elif BOOST_FUNCTION_NUM_ARGS == 35
    186291#  ifndef BOOST_FUNCTION_35
    187292#    define BOOST_FUNCTION_35
     293#    define BOOST_FUNCTION_BE_SAFE
    188294#    include <boost/function/function_template.hpp>
     295#    undef BOOST_FUNCTION_BE_SAFE
     296#    include <boost/function/function_template.hpp>
    189297#  endif
    190298#elif BOOST_FUNCTION_NUM_ARGS == 36
    191299#  ifndef BOOST_FUNCTION_36
    192300#    define BOOST_FUNCTION_36
     301#    define BOOST_FUNCTION_BE_SAFE
    193302#    include <boost/function/function_template.hpp>
     303#    undef BOOST_FUNCTION_BE_SAFE
     304#    include <boost/function/function_template.hpp>
    194305#  endif
    195306#elif BOOST_FUNCTION_NUM_ARGS == 37
    196307#  ifndef BOOST_FUNCTION_37
    197308#    define BOOST_FUNCTION_37
     309#    define BOOST_FUNCTION_BE_SAFE
    198310#    include <boost/function/function_template.hpp>
     311#    undef BOOST_FUNCTION_BE_SAFE
     312#    include <boost/function/function_template.hpp>
    199313#  endif
    200314#elif BOOST_FUNCTION_NUM_ARGS == 38
    201315#  ifndef BOOST_FUNCTION_38
    202316#    define BOOST_FUNCTION_38
     317#    define BOOST_FUNCTION_BE_SAFE
    203318#    include <boost/function/function_template.hpp>
     319#    undef BOOST_FUNCTION_BE_SAFE
     320#    include <boost/function/function_template.hpp>
    204321#  endif
    205322#elif BOOST_FUNCTION_NUM_ARGS == 39
    206323#  ifndef BOOST_FUNCTION_39
    207324#    define BOOST_FUNCTION_39
     325#    define BOOST_FUNCTION_BE_SAFE
    208326#    include <boost/function/function_template.hpp>
     327#    undef BOOST_FUNCTION_BE_SAFE
     328#    include <boost/function/function_template.hpp>
    209329#  endif
    210330#elif BOOST_FUNCTION_NUM_ARGS == 40
    211331#  ifndef BOOST_FUNCTION_40
    212332#    define BOOST_FUNCTION_40
     333#    define BOOST_FUNCTION_BE_SAFE
    213334#    include <boost/function/function_template.hpp>
     335#    undef BOOST_FUNCTION_BE_SAFE
     336#    include <boost/function/function_template.hpp>
    214337#  endif
    215338#elif BOOST_FUNCTION_NUM_ARGS == 41
    216339#  ifndef BOOST_FUNCTION_41
    217340#    define BOOST_FUNCTION_41
     341#    define BOOST_FUNCTION_BE_SAFE
    218342#    include <boost/function/function_template.hpp>
     343#    undef BOOST_FUNCTION_BE_SAFE
     344#    include <boost/function/function_template.hpp>
    219345#  endif
    220346#elif BOOST_FUNCTION_NUM_ARGS == 42
    221347#  ifndef BOOST_FUNCTION_42
    222348#    define BOOST_FUNCTION_42
     349#    define BOOST_FUNCTION_BE_SAFE
    223350#    include <boost/function/function_template.hpp>
     351#    undef BOOST_FUNCTION_BE_SAFE
     352#    include <boost/function/function_template.hpp>
    224353#  endif
    225354#elif BOOST_FUNCTION_NUM_ARGS == 43
    226355#  ifndef BOOST_FUNCTION_43
    227356#    define BOOST_FUNCTION_43
     357#    define BOOST_FUNCTION_BE_SAFE
    228358#    include <boost/function/function_template.hpp>
     359#    undef BOOST_FUNCTION_BE_SAFE
     360#    include <boost/function/function_template.hpp>
    229361#  endif
    230362#elif BOOST_FUNCTION_NUM_ARGS == 44
    231363#  ifndef BOOST_FUNCTION_44
    232364#    define BOOST_FUNCTION_44
     365#    define BOOST_FUNCTION_BE_SAFE
    233366#    include <boost/function/function_template.hpp>
     367#    undef BOOST_FUNCTION_BE_SAFE
     368#    include <boost/function/function_template.hpp>
    234369#  endif
    235370#elif BOOST_FUNCTION_NUM_ARGS == 45
    236371#  ifndef BOOST_FUNCTION_45
    237372#    define BOOST_FUNCTION_45
     373#    define BOOST_FUNCTION_BE_SAFE
    238374#    include <boost/function/function_template.hpp>
     375#    undef BOOST_FUNCTION_BE_SAFE
     376#    include <boost/function/function_template.hpp>
    239377#  endif
    240378#elif BOOST_FUNCTION_NUM_ARGS == 46
    241379#  ifndef BOOST_FUNCTION_46
    242380#    define BOOST_FUNCTION_46
     381#    define BOOST_FUNCTION_BE_SAFE
    243382#    include <boost/function/function_template.hpp>
     383#    undef BOOST_FUNCTION_BE_SAFE
     384#    include <boost/function/function_template.hpp>
    244385#  endif
    245386#elif BOOST_FUNCTION_NUM_ARGS == 47
    246387#  ifndef BOOST_FUNCTION_47
    247388#    define BOOST_FUNCTION_47
     389#    define BOOST_FUNCTION_BE_SAFE
    248390#    include <boost/function/function_template.hpp>
     391#    undef BOOST_FUNCTION_BE_SAFE
     392#    include <boost/function/function_template.hpp>
    249393#  endif
    250394#elif BOOST_FUNCTION_NUM_ARGS == 48
    251395#  ifndef BOOST_FUNCTION_48
    252396#    define BOOST_FUNCTION_48
     397#    define BOOST_FUNCTION_BE_SAFE
    253398#    include <boost/function/function_template.hpp>
     399#    undef BOOST_FUNCTION_BE_SAFE
     400#    include <boost/function/function_template.hpp>
    254401#  endif
    255402#elif BOOST_FUNCTION_NUM_ARGS == 49
    256403#  ifndef BOOST_FUNCTION_49
    257404#    define BOOST_FUNCTION_49
     405#    define BOOST_FUNCTION_BE_SAFE
    258406#    include <boost/function/function_template.hpp>
     407#    undef BOOST_FUNCTION_BE_SAFE
     408#    include <boost/function/function_template.hpp>
    259409#  endif
    260410#elif BOOST_FUNCTION_NUM_ARGS == 50
    261411#  ifndef BOOST_FUNCTION_50
    262412#    define BOOST_FUNCTION_50
     413#    define BOOST_FUNCTION_BE_SAFE
    263414#    include <boost/function/function_template.hpp>
     415#    undef BOOST_FUNCTION_BE_SAFE
     416#    include <boost/function/function_template.hpp>
    264417#  endif
    265418#else
    266419#  error Cannot handle Boost.Function objects that accept more than 50 arguments!
  • boost/function/function_template.hpp

     
    4141#endif // BOOST_FUNCTION_NUM_ARGS > 0
    4242
    4343// Class names used in this version of the code
    44 #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
     44#define BOOST_FUNCTION_SAFE_WRAPPER function
     45#define BOOST_FUNCTION_UNSAFE_WRAPPER unsafe_function
     46#define BOOST_FUNCTION_SAFE_FUNCTION BOOST_JOIN(BOOST_FUNCTION_SAFE_WRAPPER,BOOST_FUNCTION_NUM_ARGS)
     47#define BOOST_FUNCTION_UNSAFE_FUNCTION BOOST_JOIN(BOOST_FUNCTION_UNSAFE_WRAPPER,BOOST_FUNCTION_NUM_ARGS)
     48#if defined(BOOST_FUNCTION_BE_SAFE)
     49#  define BOOST_FUNCTION_WRAPPER BOOST_FUNCTION_SAFE_WRAPPER
     50#else
     51#  define BOOST_FUNCTION_WRAPPER BOOST_FUNCTION_UNSAFE_WRAPPER
     52#endif
     53#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(BOOST_FUNCTION_WRAPPER,BOOST_FUNCTION_NUM_ARGS)
    4554#define BOOST_FUNCTION_FUNCTION_INVOKER \
    4655  BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
    4756#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
     
    7988#endif
    8089
    8190namespace boost {
     91#if defined(BOOST_FUNCTION_BE_SAFE)
    8292  namespace detail {
    8393    namespace function {
    8494      template<
     
    645655    } // end namespace function
    646656  } // end namespace detail
    647657
     658  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
     659  class BOOST_FUNCTION_UNSAFE_FUNCTION;
     660#endif // BOOST_FUNCTION_BE_SAFE
     661
    648662  template<
    649663    typename R BOOST_FUNCTION_COMMA
    650664    BOOST_FUNCTION_TEMPLATE_PARMS
     
    749763      this->assign_to_own(f);
    750764    }
    751765
     766    BOOST_FUNCTION_FUNCTION(
     767#if defined(BOOST_FUNCTION_BE_SAFE)
     768        const BOOST_FUNCTION_UNSAFE_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>& f
     769#else
     770        const BOOST_FUNCTION_SAFE_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>& f
     771#endif
     772    ) : function_base()
     773    {
     774      this->assign_to_own(f);
     775    }
     776
    752777    ~BOOST_FUNCTION_FUNCTION() { clear(); }
    753778
    754779#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
     
    756781    // these definitions can become very costly.
    757782    result_type operator()(BOOST_FUNCTION_PARMS) const
    758783    {
     784#if defined(BOOST_FUNCTION_BE_SAFE)
    759785      if (this->empty())
    760786        boost::throw_exception(bad_function_call());
     787#endif
    761788
    762789      return get_vtable()->invoker
    763790               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
     
    878905#endif
    879906
    880907  private:
    881     void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
     908    void assign_to_own(const function_base& f)
    882909    {
    883910      if (!f.empty()) {
    884911        this->vtable = f.vtable;
     
    10061033  BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
    10071034  ::operator()(BOOST_FUNCTION_PARMS) const
    10081035  {
     1036#if defined(BOOST_FUNCTION_BE_SAFE)
    10091037    if (this->empty())
    10101038      boost::throw_exception(bad_function_call());
     1039#endif
    10111040
    10121041    return get_vtable()->invoker
    10131042             (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
     
    10401069
    10411070template<typename R BOOST_FUNCTION_COMMA
    10421071         BOOST_FUNCTION_TEMPLATE_PARMS>
    1043 class function<BOOST_FUNCTION_PARTIAL_SPEC>
     1072class BOOST_FUNCTION_WRAPPER<BOOST_FUNCTION_PARTIAL_SPEC>
    10441073  : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
    10451074{
    10461075  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
    1047   typedef function self_type;
     1076  typedef BOOST_FUNCTION_WRAPPER self_type;
    10481077
    10491078  struct clear_type {};
    10501079
    10511080public:
    10521081
    1053   function() : base_type() {}
     1082  BOOST_FUNCTION_WRAPPER() : base_type() {}
    10541083
    10551084  template<typename Functor>
    1056   function(Functor f
     1085  BOOST_FUNCTION_WRAPPER(Functor f
    10571086#ifndef BOOST_NO_SFINAE
    10581087           ,typename enable_if_c<
    10591088                            (boost::type_traits::ice_not<
     
    10651094  {
    10661095  }
    10671096  template<typename Functor,typename Allocator>
    1068   function(Functor f, Allocator a
     1097  BOOST_FUNCTION_WRAPPER(Functor f, Allocator a
    10691098#ifndef BOOST_NO_SFINAE
    10701099           ,typename enable_if_c<
    10711100                            (boost::type_traits::ice_not<
     
    10781107  }
    10791108
    10801109#ifndef BOOST_NO_SFINAE
    1081   function(clear_type*) : base_type() {}
     1110  BOOST_FUNCTION_WRAPPER(clear_type*) : base_type() {}
    10821111#endif
    10831112
    1084   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
     1113  BOOST_FUNCTION_WRAPPER(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
    10851114
    1086   function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
     1115  BOOST_FUNCTION_WRAPPER(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
    10871116
     1117#if defined(BOOST_FUNCTION_BE_SAFE)
     1118  BOOST_FUNCTION_WRAPPER(const BOOST_FUNCTION_UNSAFE_WRAPPER<BOOST_FUNCTION_PARTIAL_SPEC>& f)
     1119    : base_type(
     1120        static_cast<
     1121          const BOOST_FUNCTION_UNSAFE_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>&
     1122        >(f)
     1123      ) {}
     1124#else
     1125  BOOST_FUNCTION_WRAPPER(const BOOST_FUNCTION_SAFE_WRAPPER<BOOST_FUNCTION_PARTIAL_SPEC>& f)
     1126    : base_type(
     1127        static_cast<
     1128          const BOOST_FUNCTION_SAFE_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>&
     1129        >(f)
     1130      ) {}
     1131#endif
     1132
    10881133  self_type& operator=(const self_type& f)
    10891134  {
    10901135    self_type(f).swap(*this);
     
    11191164    self_type(f).swap(*this);
    11201165    return *this;
    11211166  }
     1167
     1168#if defined(BOOST_FUNCTION_BE_SAFE)
     1169  self_type& operator=(const BOOST_FUNCTION_UNSAFE_WRAPPER<BOOST_FUNCTION_PARTIAL_SPEC>& f)
     1170#else
     1171  self_type& operator=(const BOOST_FUNCTION_SAFE_WRAPPER<BOOST_FUNCTION_PARTIAL_SPEC>& f)
     1172#endif
     1173  {
     1174    self_type(f).swap(*this);
     1175    return *this;
     1176  }
    11221177};
    11231178
    11241179#undef BOOST_FUNCTION_PARTIAL_SPEC
     
    11271182} // end namespace boost
    11281183
    11291184// Cleanup after ourselves...
     1185#undef BOOST_FUNCTION_SAFE_WRAPPER
     1186#undef BOOST_FUNCTION_UNSAFE_WRAPPER
     1187#undef BOOST_FUNCTION_SAFE_FUNCTION
     1188#undef BOOST_FUNCTION_UNSAFE_FUNCTION
     1189#undef BOOST_FUNCTION_WRAPPER
    11301190#undef BOOST_FUNCTION_VTABLE
    11311191#undef BOOST_FUNCTION_COMMA
    11321192#undef BOOST_FUNCTION_FUNCTION
  • boost/function/function_fwd.hpp

     
    3737  {
    3838    f1.swap(f2);
    3939  }
     40
     41  template<typename Signature> class unsafe_function;
     42
     43  template<typename Signature>
     44  inline void swap(unsafe_function<Signature>& f1, unsafe_function<Signature>& f2)
     45  {
     46    f1.swap(f2);
     47  }
     48
     49  template<typename Signature>
     50  inline void swap(unsafe_function<Signature>& f1, function<Signature>& f2)
     51  {
     52    unsafe_function<Signature> tmp = f1;
     53    f1 = f2;
     54    f2 = tmp;
     55  }
     56
     57  template<typename Signature>
     58  inline void swap(function<Signature>& f1, unsafe_function<Signature>& f2)
     59  {
     60    swap(f2, f1);
     61  }
    4062#endif // have partial specialization
    4163
    4264  // Portable syntax
  • libs/function/test/Jamfile.v2

     
    6262  [ run libs/function/test/nothrow_swap.cpp :  :  :  :  ]
    6363
    6464  [ compile libs/function/test/function_typeof_test.cpp ]
     65
     66  [ run libs/function/test/unsafe_function_cxx98.cpp :  :  :  :  ]
     67
     68  [ run libs/function/test/no_exceptions.cpp :  :  :  :  ]
    6569 ;
    6670}
    6771     
  • libs/function/test/no_exceptions.cpp

     
     1// Boost.Function library
     2//
     3//  Copyright Daniel Walker 2010. Use, modification and distribution
     4//  are subject to the Boost Software License, Version 1.0. (See
     5//  accompanying file LICENSE_1_0.txt or copy at
     6//  http://www.boost.org/LICENSE_1_0.txt)
     7//
     8// For more information, see http://www.boost.org/libs/function
     9//
     10
     11// Briefly check that boost::unsafe_function works out-of-the-box
     12// when Boost exceptions are not available.
     13
     14#include <cassert>
     15
     16#define BOOST_NO_EXCEPTIONS
     17#include <boost/function.hpp>
     18
     19int f(int x) { return x; }
     20
     21int main(int, char*[])
     22{
     23    boost::unsafe_function1<int, int>  g = &f;
     24    assert(g);
     25    assert(g == &f);
     26    assert(f(0xABCD) == 0xABCD);
     27    assert(g(0xABCD) == 0xABCD);
     28    return 0;
     29}
  • libs/function/test/unsafe_function_cxx98.cpp

     
     1// Boost.Function library
     2//
     3//  Copyright Daniel Walker 2010. Use, modification and distribution
     4//  are subject to the Boost Software License, Version 1.0. (See
     5//  accompanying file LICENSE_1_0.txt or copy at
     6//  http://www.boost.org/LICENSE_1_0.txt)
     7//
     8// For more information, see http://www.boost.org/libs/function
     9//
     10
     11// Since the same preprocessor boilerplate is used to generate both
     12// boost::function and boost::unsafe_function, the API tests are
     13// performed on boost::function and are not duplicated for
     14// boost::unsafe_function. The only new methods specific to
     15// boost::unsafe_function are swap, construction and assignment
     16// with boost::function, which are tested below.
     17
     18#include <boost/test/minimal.hpp>
     19
     20#include <boost/function.hpp>
     21#include <boost/timer.hpp>
     22
     23int f(int x) { return x; }
     24
     25int test_main(int, char*[])
     26{
     27    // Sanity check: construction, assignment, comparison and
     28    // call-operator.
     29    {
     30        boost::unsafe_function<int(int)> g(&f);
     31        BOOST_REQUIRE(g);
     32        BOOST_REQUIRE(g == &f);
     33        boost::unsafe_function<int(int)> h;
     34        BOOST_REQUIRE(!h);
     35        h = &f;
     36        BOOST_REQUIRE(h);
     37        BOOST_REQUIRE(h == &f);
     38        BOOST_REQUIRE(f(0xABCD) == 0xABCD);
     39        BOOST_REQUIRE(h(0xABCD) == 0xABCD);
     40    }
     41
     42    // Swap.
     43    {
     44        boost::unsafe_function<int(int)> g, h(&f);
     45        boost::swap(g, h);
     46        BOOST_REQUIRE(!h);
     47        BOOST_REQUIRE(g);
     48        BOOST_REQUIRE(g == &f);
     49    }
     50
     51    // Construction from boost::function.
     52    {
     53        boost::function<int(int)> g = &f;
     54        boost::unsafe_function<int(int)> h(g);
     55        BOOST_REQUIRE(h == &f);
     56    }
     57
     58    // Assignment from boost::function.
     59    {
     60        boost::function<int(int)> g = &f;
     61        boost::unsafe_function<int(int)> h;
     62        h = g;
     63        BOOST_REQUIRE(h == &f);
     64    }
     65
     66    // Construction from boost::unsafe_function.
     67    {
     68        boost::unsafe_function<int(int)> g = &f;
     69        boost::function<int(int)> h(g);
     70        BOOST_REQUIRE(h == &f);
     71    }
     72
     73    // Assignment from boost::unsafe_function.
     74    {
     75        boost::unsafe_function<int(int)> g = &f;
     76        boost::function<int(int)> h;
     77        h = g;
     78        BOOST_REQUIRE(h == &f);
     79    }
     80
     81    // Swap with boost::function.
     82    {
     83        boost::function<int(int)> g;
     84        boost::unsafe_function<int(int)> h(&f);
     85        boost::swap(g, h);
     86        BOOST_REQUIRE(!h);
     87        BOOST_REQUIRE(g == &f);
     88        boost::swap(h, g);
     89        BOOST_REQUIRE(!g);
     90        BOOST_REQUIRE(h == &f);
     91    }
     92
     93    // In unoptimized object code, boost::unsafe_function should have
     94    // less runtime cost than boost::function.
     95    #ifndef NDEBUG
     96    {
     97        int n = INT_MAX/4;
     98        boost::function<int(int)> g = &f;
     99        boost::timer t;
     100        for(int i = 0; i < n; ++i)
     101            g(i);
     102        const double function_cost = t.elapsed();
     103
     104        boost::unsafe_function<int(int)> h = g;
     105        t.restart();
     106        for(int i = 0; i < n; ++i)
     107            h(i);
     108        const double unsafe_function_cost = t.elapsed();
     109        BOOST_CHECK(unsafe_function_cost <= function_cost*1.1);
     110    }
     111    #endif
     112    return 0;
     113}
  • libs/function/doc/tutorial.xml

     
    159159
    160160<para> Invoking a function object wrapper that does not actually
    161161contain a function object is a precondition violation, much like
    162 trying to call through a null function pointer, and will throw a <classname>bad_function_call</classname> exception). We can check for an
     162trying to call through a null function
     163pointer. <classname>boost::function</classname> will throw
     164a <classname>bad_function_call</classname> exception when invoked
     165with no target.
     166Alternatively, <classname alt="function">boost::unsafe_function</classname>
     167has no exception safety guarantee and puts the onus on the user to
     168check if it is empty prior to attempting a call. We can check for an
    163169empty function object wrapper by using it in a boolean context (it evaluates <computeroutput>true</computeroutput> if the wrapper is not empty) or compare it against <computeroutput>0</computeroutput>. For instance:
    164170<programlisting name="function.tutorial.check_empty">if (f)
    165171  std::cout &lt;&lt; f(5, 3) &lt;&lt; std::endl;
     
    360366
    361367</section>
    362368
     369<section>
     370  <title>Boost.Function exception safety</title>
     371  <para>Boost.Function provides function object wrappers with two
     372  levels of exception safety. A strong exception safety guarantee is
     373  provided by <classname>boost::function</classname>, which will
     374  either call the target function or
     375  throw <classname>bad_function_call</classname> if it has no
     376  target. <classname>boost::function</classname>
     377  uses <functionname>boost::throw_exception</functionname> and can be
     378  further configured via the
     379  Boost <libraryname>Exception</libraryname> Library.</para>
     380
     381  <para>In circumstances where no exception safety guarantee is
     382  desirable, such as some embedded
     383  systems, <classname alt="function">boost::unsafe_function</classname>
     384  may be used as a direct substitute
     385  for <classname>boost::function</classname>, with the caveat that the
     386  behavior
     387  of <classname alt="function">boost::unsafe_function</classname> is
     388  undefined when invoked with no target. For example, the following
     389  demonstrates how to
     390  handle <classname>boost::function</classname>
     391  and <classname alt="function">boost::unsafe_function</classname>
     392  when their preconditions are violated:
     393  <informaltable>
     394    <tgroup cols="2" align="left">
     395      <thead>
     396        <row>
     397          <entry>Preferred syntax</entry>
     398          <entry>Portable syntax</entry>
     399        </row>
     400      </thead>
     401      <tbody>
     402        <row>
     403          <entry>
     404<programlisting name="function.tutorial.unsafe.cxx98"><classname>boost::function</classname>&lt;void ()&gt; f;
     405<classname alt="function">boost::unsafe_function</classname>&lt;void ()&gt; g;</programlisting>
     406</entry>
     407<entry>
     408<programlisting name="function.tutorial.unsafe.portable"><classname alt="functionN">boost::function0</classname>&lt;void&gt; f;
     409<classname alt="functionN">boost::unsafe_function0</classname>&lt;void&gt; g;</programlisting>
     410</entry>
     411          </row>
     412        </tbody>
     413      </tgroup>
     414    </informaltable>
     415<programlisting name="function.tutorial.unsafe">try {
     416  f(); // throws bad_function_call
     417}
     418catch(boost::bad_function_call e) {
     419  std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
     420}
     421
     422if(g)
     423  g(); // undefined behavior
     424else
     425  std::cerr &lt;&lt; "boost::unsafe_function is empty" &lt;&lt; std::endl;</programlisting></para>
     426
     427  <para>More information about exception safety guarantees in C++ may
     428  be found <ulink url="http://www.boost.org/community/exception_safety.html">here</ulink>.</para>
    363429</section>
    364430
     431</section>
     432
  • libs/function/doc/faq.xml

     
    153153      standard function pointer, differences of order of 10% have been
    154154      noted to the benefit or disadvantage of using
    155155      <code>boost::function</code> to call a function that contains a
    156       tight loop depending on your compilation circumstances.</para>
     156      tight loop depending on your compilation circumstances.*</para>
    157157     
    158       <para>[Answer provided by Matt Hurd. See <ulink url="http://article.gmane.org/gmane.comp.lib.boost.devel/33278"/>]</para>
     158      <para>The difference in overhead
     159      between <code>boost::unsafe_function</code>
     160      and <code>boost::function</code> will vary according to the
     161      optimization strategy of your compiler. For example, their
     162      performance is almost the same (within a few hundred
     163      picoseconds) using MSVC Release mode or <code>gcc
     164      -O2</code>.</para>
     165
     166      <para>[*Answer provided by Matt Hurd. See <ulink url="http://article.gmane.org/gmane.comp.lib.boost.devel/33278"/>]</para>
    159167    </answer>
    160168  </qandaentry>
    161169</qandaset>
  • libs/function/doc/reference.xml

     
    153153      alt="functionN">function0</classname>, <classname
    154154      alt="functionN">function1</classname>, etc., up to some
    155155      implementation-defined maximum. In this context, <code>N</code>
    156       refers to the number of parameters.</para>
     156      refers to the number of parameters. The corresponding class
     157      template <classname alt="functionN">unsafe_fuctionN</classname>
     158      has no exception safety guarantee when invoked with no
     159      target.</para>
    157160    </description>
    158161
    159162    <typedef name="result_type"><type>R</type></typedef>
     
    322325        <parameter name="aN"><paramtype>argN_type</paramtype></parameter>
    323326        <effects><simpara><code>f(a1, a2, ..., aN)</code>, where <code>f</code> is the target of <code>*this</code>.</simpara></effects>
    324327        <returns><simpara>if <code>R</code> is <code>void</code>, nothing is returned; otherwise, the return value of the call to <code>f</code> is returned.</simpara></returns>
    325         <throws><simpara><code><classname>bad_function_call</classname></code> if <code>this-&gt;<methodname>empty</methodname>()</code>. Otherwise, may through any exception thrown by the target function <code>f</code>.</simpara></throws>
     328        <throws><simpara><code><classname>bad_function_call</classname></code> if <code>this-&gt;<methodname>empty</methodname>()</code>. Otherwise, may through any exception thrown by the target function <code>f</code>. The behavior of <classname alt="functionN">unsafe_functionN</classname> is undefined if <code>this-&gt;<methodname>empty</methodname>()</code>.</simpara></throws>
    326329      </method>
    327330    </method-group>
    328331
     
    558561      <classname>function</classname> are equivalent to that of the
    559562      underlying <classname>functionN</classname> object, although
    560563      additional member functions are required to allow proper copy
    561       construction and copy assignment of function objects.</para>
     564      construction and copy assignment of function objects. The
     565      corresponding class
     566      template <classname alt="function">unsafe_fuction</classname>
     567      has no exception safety guarantee when invoked with no
     568      target.</para>
    562569    </description>
    563570
    564571    <typedef name="result_type"><type>R</type></typedef>
     
    742749        <parameter name="aN"><paramtype>argN_type</paramtype></parameter>
    743750        <effects><simpara><code>f(a1, a2, ..., aN)</code>, where <code>f</code> is the target of <code>*this</code>.</simpara></effects>
    744751        <returns><simpara>if <code>R</code> is <code>void</code>, nothing is returned; otherwise, the return value of the call to <code>f</code> is returned.</simpara></returns>
    745         <throws><simpara><code><classname>bad_function_call</classname></code> if <code>this-&gt;<methodname>empty</methodname>()</code>. Otherwise, may through any exception thrown by the target function <code>f</code>.</simpara></throws>
     752        <throws><simpara><code><classname>bad_function_call</classname></code> if <code>this-&gt;<methodname>empty</methodname>()</code>. Otherwise, may through any exception thrown by the target function <code>f</code>. The behavior of <classname alt="function">unsafe_function</classname> is undefined if <code>this-&gt;<methodname>empty</methodname>()</code>.</simpara></throws>
    746753      </method>
    747754    </method-group>
    748755
  • libs/function/example/exception_safety.cpp

     
     1// Boost.Function library example
     2//
     3//  Copyright Daniel Walker 2010. Use, modification and distribution
     4//  are subject to the Boost Software License, Version 1.0. (See
     5//  accompanying file LICENSE_1_0.txt or copy at
     6//  http://www.boost.org/LICENSE_1_0.txt)
     7//
     8// For more information, see http://www.boost.org/libs/function
     9//
     10
     11// This example demonstrates how to handle boost::function and
     12// boost::unsafe_function when their preconditions are violated.
     13
     14#include <iostream>
     15#include <boost/function.hpp>
     16
     17int main(int, char*[])
     18{
     19    boost::function<void ()> f;
     20    boost::unsafe_function<void ()> g;
     21
     22    try {
     23        f(); // throws bad_function_call
     24    }
     25    catch(boost::bad_function_call e) {
     26        std::cerr << e.what() << std::endl;
     27    }
     28
     29    if(g)
     30        g(); // undefined behavior
     31    else
     32        std::cerr << "boost::unsafe_function is empty" << std::endl;
     33
     34    return 0;
     35}