Ticket #4803: djw_function_static_empty.patch
File djw_function_static_empty.patch, 23.0 KB (added by , 12 years ago) |
---|
-
boost/function/function_template.hpp
69 69 #define BOOST_FUNCTION_GET_INVOKER \ 70 70 BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) 71 71 #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) 72 #define BOOST_FUNCTION_EMPTY_FUNCTION \ 73 BOOST_JOIN(empty_function, BOOST_FUNCTION_NUM_ARGS) 72 74 73 75 #ifndef BOOST_NO_VOID_RETURNS 74 76 # define BOOST_FUNCTION_VOID_RETURN_TYPE void … … 79 81 #endif 80 82 81 83 namespace boost { 84 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 85 template< 86 typename R BOOST_FUNCTION_COMMA 87 BOOST_FUNCTION_TEMPLATE_PARMS 88 > 89 class BOOST_FUNCTION_FUNCTION; 90 91 # if !defined(BOOST_NO_SFINAE) 92 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> 93 inline bool operator==(const BOOST_FUNCTION_FUNCTION< 94 R BOOST_FUNCTION_COMMA 95 BOOST_FUNCTION_TEMPLATE_ARGS>& f, 96 detail::function::useless_clear_type*) 97 { 98 return f.empty(); 99 } 100 101 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> 102 inline bool operator!=(const BOOST_FUNCTION_FUNCTION< 103 R BOOST_FUNCTION_COMMA 104 BOOST_FUNCTION_TEMPLATE_ARGS>& f, 105 detail::function::useless_clear_type*) 106 { 107 return !f.empty(); 108 } 109 110 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> 111 inline bool operator==(detail::function::useless_clear_type*, 112 const BOOST_FUNCTION_FUNCTION< 113 R BOOST_FUNCTION_COMMA 114 BOOST_FUNCTION_TEMPLATE_ARGS>& f) 115 { 116 return f.empty(); 117 } 118 119 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> 120 inline bool operator!=(detail::function::useless_clear_type*, 121 const BOOST_FUNCTION_FUNCTION< 122 R BOOST_FUNCTION_COMMA 123 BOOST_FUNCTION_TEMPLATE_ARGS>& f) 124 { 125 return !f.empty(); 126 } 127 # endif // !defined(BOOST_NO_SFINAE) 128 82 129 namespace detail { 83 130 namespace function { 131 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> 132 inline bool has_empty_target(const BOOST_FUNCTION_FUNCTION< 133 R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS 134 >* f) 135 { 136 return f->empty(); 137 } 138 84 139 template< 140 typename R BOOST_FUNCTION_COMMA 141 BOOST_FUNCTION_TEMPLATE_PARMS 142 > 143 R BOOST_FUNCTION_EMPTY_FUNCTION(BOOST_FUNCTION_PARMS) 144 { 145 BOOST_FUNCTION_RETURN(boost::throw_exception(bad_function_call())); 146 } 147 } // namespace function 148 } // namespace detail 149 #endif // BOOST_FUNCTION_USE_STATIC_EMPTY 150 151 namespace detail { 152 namespace function { 153 template< 85 154 typename FunctionPtr, 86 155 typename R BOOST_FUNCTION_COMMA 87 156 BOOST_FUNCTION_TEMPLATE_PARMS … … 486 555 BOOST_FUNCTION_TEMPLATE_ARGS); 487 556 488 557 template<typename F> 489 bool assign_to(F f, function_buffer& functor) 558 bool assign_to(F f, function_buffer& functor) const 490 559 { 491 560 typedef typename get_function_tag<F>::type tag; 492 561 return assign_to(f, functor, tag()); 493 562 } 494 563 template<typename F,typename Allocator> 495 bool assign_to_a(F f, function_buffer& functor, Allocator a) 564 bool assign_to_a(F f, function_buffer& functor, Allocator a) const 496 565 { 497 566 typedef typename get_function_tag<F>::type tag; 498 567 return assign_to_a(f, functor, a, tag()); 499 568 } 500 569 501 void clear(function_buffer& functor) 570 void clear(function_buffer& functor) const 502 571 { 503 572 if (base.manager) 504 573 base.manager(functor, functor, destroy_functor_tag); … … 508 577 // Function pointers 509 578 template<typename FunctionPtr> 510 579 bool 511 assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) 580 assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const 512 581 { 513 582 this->clear(functor); 514 583 if (f) { … … 522 591 } 523 592 template<typename FunctionPtr,typename Allocator> 524 593 bool 525 assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) 594 assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const 526 595 { 527 596 return assign_to(f,functor,function_ptr_tag()); 528 597 } … … 530 599 // Member pointers 531 600 #if BOOST_FUNCTION_NUM_ARGS > 0 532 601 template<typename MemberPtr> 533 bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) 602 bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const 534 603 { 535 604 // DPG TBD: Add explicit support for member function 536 605 // objects, so we invoke through mem_fn() but we retain the … … 543 612 } 544 613 } 545 614 template<typename MemberPtr,typename Allocator> 546 bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) 615 bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const 547 616 { 548 617 // DPG TBD: Add explicit support for member function 549 618 // objects, so we invoke through mem_fn() but we retain the … … 561 630 // Assign to a function object using the small object optimization 562 631 template<typename FunctionObj> 563 632 void 564 assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) 633 assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const 565 634 { 566 635 new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f); 567 636 } 568 637 template<typename FunctionObj,typename Allocator> 569 638 void 570 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) 639 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const 571 640 { 572 641 assign_functor(f,functor,mpl::true_()); 573 642 } … … 575 644 // Assign to a function object allocated on the heap. 576 645 template<typename FunctionObj> 577 646 void 578 assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) 647 assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const 579 648 { 580 649 functor.obj_ptr = new FunctionObj(f); 581 650 } 582 651 template<typename FunctionObj,typename Allocator> 583 652 void 584 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) 653 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const 585 654 { 586 655 typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type; 587 656 typedef typename Allocator::template rebind<functor_wrapper_type>::other … … 596 665 597 666 template<typename FunctionObj> 598 667 bool 599 assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) 668 assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const 600 669 { 601 670 if (!boost::detail::function::has_empty_target(boost::addressof(f))) { 602 671 assign_functor(f, functor, … … 608 677 } 609 678 template<typename FunctionObj,typename Allocator> 610 679 bool 611 assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) 680 assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const 612 681 { 613 682 if (!boost::detail::function::has_empty_target(boost::addressof(f))) { 614 683 assign_functor_a(f, functor, a, … … 623 692 template<typename FunctionObj> 624 693 bool 625 694 assign_to(const reference_wrapper<FunctionObj>& f, 626 function_buffer& functor, function_obj_ref_tag) 695 function_buffer& functor, function_obj_ref_tag) const 627 696 { 628 697 functor.obj_ref.obj_ptr = (void *)(f.get_pointer()); 629 698 functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value; … … 633 702 template<typename FunctionObj,typename Allocator> 634 703 bool 635 704 assign_to_a(const reference_wrapper<FunctionObj>& f, 636 function_buffer& functor, Allocator, function_obj_ref_tag) 705 function_buffer& functor, Allocator, function_obj_ref_tag) const 637 706 { 638 707 return assign_to(f,functor,function_obj_ref_tag()); 639 708 } … … 682 751 683 752 struct clear_type {}; 684 753 754 typedef R (*empty_function_type)(BOOST_FUNCTION_TEMPLATE_ARGS); 755 685 756 public: 686 757 BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); 687 758 … … 704 775 705 776 typedef BOOST_FUNCTION_FUNCTION self_type; 706 777 707 BOOST_FUNCTION_FUNCTION() : function_base() { } 778 BOOST_FUNCTION_FUNCTION() : function_base() 779 { 780 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 781 this->assign_empty(); 782 #endif 783 } 708 784 709 785 // MSVC chokes if the following two constructors are collapsed into 710 786 // one with a default parameter. … … 736 812 } 737 813 738 814 #ifndef BOOST_NO_SFINAE 739 BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } 815 BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() 816 { 817 # ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 818 this->assign_empty(); 819 # endif 820 } 740 821 #else 741 822 BOOST_FUNCTION_FUNCTION(int zero) : function_base() 742 823 { 743 824 BOOST_ASSERT(zero == 0); 825 # ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 826 this->assign_empty(); 827 # endif 744 828 } 745 829 #endif 746 830 … … 756 840 // these definitions can become very costly. 757 841 result_type operator()(BOOST_FUNCTION_PARMS) const 758 842 { 843 # ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 844 BOOST_ASSERT(vtable); 845 # else 759 846 if (this->empty()) 760 847 boost::throw_exception(bad_function_call()); 848 # endif 761 849 762 850 return get_vtable()->invoker 763 851 (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); … … 786 874 BOOST_TRY { 787 875 this->assign_to(f); 788 876 } BOOST_CATCH (...) { 877 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 878 this->assign_empty(); 879 #else 789 880 vtable = 0; 881 #endif 790 882 BOOST_RETHROW; 791 883 } 792 884 BOOST_CATCH_END … … 799 891 BOOST_TRY{ 800 892 this->assign_to_a(f,a); 801 893 } BOOST_CATCH (...) { 894 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 895 this->assign_empty(); 896 #else 802 897 vtable = 0; 898 #endif 803 899 BOOST_RETHROW; 804 900 } 805 901 BOOST_CATCH_END … … 830 926 BOOST_TRY { 831 927 this->assign_to_own(f); 832 928 } BOOST_CATCH (...) { 929 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 930 this->assign_empty(); 931 #else 833 932 vtable = 0; 933 #endif 834 934 BOOST_RETHROW; 835 935 } 836 936 BOOST_CATCH_END … … 848 948 other.move_assign(tmp); 849 949 } 850 950 951 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 952 // Determine if the function is empty (i.e., has no target). 953 bool empty() const 954 { 955 empty_function_type const* ptr = target<empty_function_type>(); 956 empty_function_type empty_ptr = &detail::function::BOOST_FUNCTION_EMPTY_FUNCTION< 957 R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>; 958 return ptr ? *ptr == empty_ptr : false; 959 } 960 851 961 // Clear out a target, if there is one 852 962 void clear() 853 963 { 964 if (!this->empty()) { 965 if (!this->has_trivial_copy_and_destroy()) 966 get_vtable()->clear(this->functor); 967 this->assign_empty(); 968 } 969 } 970 #else // BOOST_FUNCTION_USE_STATIC_EMPTY 971 // Clear out a target, if there is one 972 void clear() 973 { 854 974 if (vtable) { 855 975 if (!this->has_trivial_copy_and_destroy()) 856 976 get_vtable()->clear(this->functor); 857 977 vtable = 0; 858 978 } 859 979 } 980 #endif // BOOST_FUNCTION_USE_STATIC_EMPTY 860 981 861 982 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) 862 983 // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it … … 888 1009 get_vtable()->base.manager(f.functor, this->functor, 889 1010 boost::detail::function::clone_functor_tag); 890 1011 } 1012 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1013 else 1014 this->assign_empty(); 1015 #endif 891 1016 } 892 1017 893 1018 template<typename Functor> … … 909 1034 // static initialization. Otherwise, we will have a race 910 1035 // condition here in multi-threaded code. See 911 1036 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. 912 static vtable_type stored_vtable =1037 static const vtable_type stored_vtable = 913 1038 { { &manager_type::manage }, &invoker_type::invoke }; 914 1039 915 1040 if (stored_vtable.assign_to(f, functor)) { … … 920 1045 value |= static_cast<size_t>(0x01); 921 1046 vtable = reinterpret_cast<detail::function::vtable_base *>(value); 922 1047 } else 1048 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1049 this->assign_empty(); 1050 #else 923 1051 vtable = 0; 1052 #endif 924 1053 } 925 1054 926 1055 template<typename Functor,typename Allocator> … … 943 1072 // static initialization. Otherwise, we will have a race 944 1073 // condition here in multi-threaded code. See 945 1074 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. 946 static vtable_type stored_vtable =1075 static const vtable_type stored_vtable = 947 1076 { { &manager_type::manage }, &invoker_type::invoke }; 948 1077 949 1078 if (stored_vtable.assign_to_a(f, functor, a)) { … … 954 1083 value |= static_cast<std::size_t>(0x01); 955 1084 vtable = reinterpret_cast<detail::function::vtable_base *>(value); 956 1085 } else 1086 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1087 this->assign_empty(); 1088 #else 957 1089 vtable = 0; 1090 #endif 958 1091 } 959 1092 960 1093 // Moves the value from the specified argument to *this. If the argument … … 973 1106 else 974 1107 get_vtable()->base.manager(f.functor, this->functor, 975 1108 boost::detail::function::move_functor_tag); 1109 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1110 f.assign_empty(); 1111 #else 976 1112 f.vtable = 0; 1113 #endif 977 1114 } else { 978 1115 clear(); 979 1116 } 980 1117 } BOOST_CATCH (...) { 1118 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1119 this->assign_empty(); 1120 #else 981 1121 vtable = 0; 1122 #endif 982 1123 BOOST_RETHROW; 983 1124 } 984 1125 BOOST_CATCH_END 985 1126 } 1127 #ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1128 void assign_empty() 1129 { 1130 this->assign_to( 1131 &detail::function::BOOST_FUNCTION_EMPTY_FUNCTION< 1132 R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> 1133 ); 1134 } 1135 1136 void assign_to(empty_function_type f) 1137 { 1138 using detail::function::vtable_base; 1139 1140 typedef typename detail::function::get_function_tag<empty_function_type>::type tag; 1141 typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker; 1142 typedef typename get_invoker:: 1143 template apply<empty_function_type, R BOOST_FUNCTION_COMMA 1144 BOOST_FUNCTION_TEMPLATE_ARGS> 1145 handler_type; 1146 1147 typedef typename handler_type::invoker_type invoker_type; 1148 typedef typename handler_type::manager_type manager_type; 1149 1150 // Note: it is extremely important that this initialization use 1151 // static initialization. Otherwise, we will have a race 1152 // condition here in multi-threaded code. See 1153 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. 1154 static const vtable_type stored_vtable = 1155 { { &manager_type::manage }, &invoker_type::invoke }; 1156 1157 // The following replicates the usual function pointer 1158 // assignment, which should always succeed for empty_function_type. 1159 const bool success = stored_vtable.assign_to(f, functor); 1160 BOOST_ASSERT(success); 1161 (void) success; // suppress unused variable warning 1162 std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base); 1163 value |= static_cast<size_t>(0x01); 1164 vtable = reinterpret_cast<detail::function::vtable_base *>(value); 1165 } 1166 #endif // BOOST_FUNCTION_USE_STATIC_EMPTY 986 1167 }; 987 1168 988 1169 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> … … 1006 1187 BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> 1007 1188 ::operator()(BOOST_FUNCTION_PARMS) const 1008 1189 { 1190 # ifdef BOOST_FUNCTION_USE_STATIC_EMPTY 1191 BOOST_ASSERT(vtable); 1192 # else 1009 1193 if (this->empty()) 1010 1194 boost::throw_exception(bad_function_call()); 1195 # endif 1011 1196 1012 1197 return get_vtable()->invoker 1013 1198 (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); … … 1127 1312 } // end namespace boost 1128 1313 1129 1314 // Cleanup after ourselves... 1315 #undef BOOST_FUNCTION_EMPTY_FUNCTION 1130 1316 #undef BOOST_FUNCTION_VTABLE 1131 1317 #undef BOOST_FUNCTION_COMMA 1132 1318 #undef BOOST_FUNCTION_FUNCTION -
libs/function/test/Jamfile.v2
20 20 test-suite function 21 21 : 22 22 [ run libs/function/test/function_test.cpp : : : : lib_function_test ] 23 [ run libs/function/test/function_test.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : lib_function_test_static_empty ] 23 24 24 25 [ run libs/function/test/function_n_test.cpp : : : : ] 26 [ run libs/function/test/function_n_test.cpp : : : <define>BOOST_FUNCTION_USE_EMPTY : function_n_test_static_empty ] 25 27 26 28 [ run libs/function/test/allocator_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ] 29 [ run libs/function/test/allocator_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : allocator_test_static_empty ] 27 30 28 31 [ run libs/function/test/stateless_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ] 32 [ run libs/function/test/stateless_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : stateless_test_static_empty ] 29 33 30 34 [ run libs/function/test/lambda_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ] 35 [ run libs/function/test/lambda_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : lambda_test_static_empty ] 31 36 32 37 [ compile-fail libs/function/test/function_test_fail1.cpp : : : : ] 38 [ compile-fail libs/function/test/function_test_fail1.cpp : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_test_fail1_static_empty ] 33 39 34 40 [ compile-fail libs/function/test/function_test_fail2.cpp : : : : ] 41 [ compile-fail libs/function/test/function_test_fail2.cpp : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_test_fail2_static_empty ] 35 42 36 43 [ compile libs/function/test/function_30.cpp : : : : ] 44 [ compile libs/function/test/function_30.cpp : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_30_static_empty ] 37 45 38 46 [ run libs/function/test/function_arith_cxx98.cpp : : : : ] 47 [ run libs/function/test/function_arith_cxx98.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_arith_cxx98_static_empty ] 39 48 40 49 [ run libs/function/test/function_arith_portable.cpp : : : : ] 50 [ run libs/function/test/function_arith_portable.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_arith_portable_static_empty ] 41 51 42 52 [ run libs/function/test/sum_avg_cxx98.cpp : : : : ] 53 [ run libs/function/test/sum_avg_cxx98.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : sum_avg_cxx98_static_empty ] 43 54 44 55 [ run libs/function/test/sum_avg_portable.cpp : : : : ] 56 [ run libs/function/test/sum_avg_portable.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : sum_avg_portable_static_empty ] 45 57 46 58 [ run libs/function/test/mem_fun_cxx98.cpp : : : : ] 59 [ run libs/function/test/mem_fun_cxx98.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : mem_fun_cxx98_static_empty ] 47 60 48 61 [ run libs/function/test/mem_fun_portable.cpp : : : : ] 62 [ run libs/function/test/mem_fun_portable.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : mem_fun_portable_static_empty ] 49 63 50 64 [ run libs/function/test/std_bind_cxx98.cpp : : : : ] 65 [ run libs/function/test/std_bind_cxx98.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : std_bind_cxx98_static_empty ] 51 66 52 67 [ run libs/function/test/std_bind_portable.cpp : : : : ] 68 [ run libs/function/test/std_bind_portable.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : std_bind_portable_static_empty ] 53 69 54 70 [ run libs/function/test/function_ref_cxx98.cpp : : : : ] 71 [ run libs/function/test/function_ref_cxx98.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_ref_cxx98_static_empty ] 55 72 56 73 [ run libs/function/test/function_ref_portable.cpp : : : : ] 74 [ run libs/function/test/function_ref_portable.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_ref_portable_static_empty ] 57 75 58 76 [ run libs/function/test/contains_test.cpp : : : : ] 77 [ run libs/function/test/contains_test.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : contains_test_static_empty ] 59 78 60 79 [ run libs/function/test/contains2_test.cpp : : : : ] 80 [ run libs/function/test/contains2_test.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : contains2_test_static_empty ] 61 81 62 82 [ run libs/function/test/nothrow_swap.cpp : : : : ] 83 [ run libs/function/test/nothrow_swap.cpp : : : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : nothrow_swap_static_empty ] 63 84 64 85 [ compile libs/function/test/function_typeof_test.cpp ] 86 [ compile libs/function/test/function_typeof_test.cpp : <define>BOOST_FUNCTION_USE_STATIC_EMPTY : function_typeof_test_static_empty ] 65 87 ; 66 88 } 67 89 -
libs/function/doc/faq.xml
145 145 <answer> 146 146 <para>The cost of <code>boost::function</code> can be reasonably 147 147 consistently measured at around 20ns +/- 10 ns on a modern >2GHz 148 platform versus directly inlining the code. </para>148 platform versus directly inlining the code.*</para> 149 149 150 150 <para>However, the performance of your application may benefit 151 151 from or be disadvantaged by <code>boost::function</code> … … 154 154 noted to the benefit or disadvantage of using 155 155 <code>boost::function</code> to call a function that contains a 156 156 tight loop depending on your compilation circumstances.</para> 157 158 <para>[Answer provided by Matt Hurd. See <ulink url="http://article.gmane.org/gmane.comp.lib.boost.devel/33278"/>]</para> 157 158 <para>By defining the macro 159 BOOST_FUNCTION_USE_STATIC_EMPTY, <code>boost::function</code> 160 can be configured to store static "empty" objects (one per call 161 signature) which may improve performance depending on your 162 optimiser at the cost of an increase in the text segment size 163 of the executable.</para> 164 165 <para>*[Answer provided by Matt Hurd. See <ulink url="http://article.gmane.org/gmane.comp.lib.boost.devel/33278"/>]</para> 159 166 </answer> 160 167 </qandaentry> 161 168 </qandaset>