From 8998778f516aa09bcf9b2223de2208376c2478b0 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 25 Apr 2015 17:45:13 +0300 Subject: [PATCH 01/11] Use Boost.TypeIndex to work with type_info to avoid bunch of workarounds and non-optimal operators. Added RTTI-off tests --- doc/reference.xml | 2 +- include/boost/function/function_base.hpp | 72 +++++++----------------- test/Jamfile.v2 | 2 + 3 files changed, 22 insertions(+), 54 deletions(-) diff --git a/doc/reference.xml b/doc/reference.xml index 843a25f..64dc663 100644 --- a/doc/reference.xml +++ b/doc/reference.xml @@ -128,7 +128,7 @@ const std::type_info& - typeid of the target function object, or typeid(void) if this->empty(). + typeid of the target function object, or typeid(void) if this->empty(). Works even with RTTI off. Will not throw. diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 9ddff20..8396fb8 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -16,9 +16,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -44,28 +44,6 @@ # pragma warning( disable : 4127 ) // "conditional expression is constant" #endif -// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info. -#ifdef BOOST_NO_STD_TYPEINFO -// Embedded VC++ does not have type_info in namespace std -# define BOOST_FUNCTION_STD_NS -#else -# define BOOST_FUNCTION_STD_NS std -#endif - -// Borrowed from Boost.Python library: determines the cases where we -// need to use std::type_info::name to compare instead of operator==. -#if defined( BOOST_NO_TYPEID ) -# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) -#elif defined(__GNUC__) \ - || defined(_AIX) \ - || ( defined(__sgi) && defined(__host_mips)) -# include -# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \ - (std::strcmp((X).name(),(Y).name()) == 0) -# else -# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) -#endif - #if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) # define BOOST_FUNCTION_TARGET_FIX(x) x #else @@ -105,7 +83,7 @@ namespace boost { // For pointers to std::type_info objects struct type_t { // (get_functor_type_tag, check_functor_type_tag). - const detail::sp_typeinfo* type; + const boost::typeindex::type_info* type; // Whether the type is const-qualified. bool const_qualified; @@ -217,12 +195,9 @@ namespace boost { case check_functor_type_tag: { - const detail::sp_typeinfo& check_type - = *out_buffer.type.type; - // Check whether we have the same type. We can add // cv-qualifiers, but we can't take them away. - if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F)) + if (*out_buffer.type.type == boost::typeindex::type_id() && (!in_buffer.obj_ref.is_const_qualified || out_buffer.type.const_qualified) && (!in_buffer.obj_ref.is_volatile_qualified @@ -234,7 +209,7 @@ namespace boost { return; case get_functor_type_tag: - out_buffer.type.type = &BOOST_SP_TYPEID(F); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified; out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified; return; @@ -294,14 +269,12 @@ namespace boost { } else if (op == destroy_functor_tag) out_buffer.func_ptr = 0; else if (op == check_functor_type_tag) { - const boost::detail::sp_typeinfo& check_type - = *out_buffer.type.type; - if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) + if (*out_buffer.type.type == boost::typeindex::type_id()) out_buffer.obj_ptr = &in_buffer.func_ptr; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &BOOST_SP_TYPEID(Functor); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } @@ -328,14 +301,12 @@ namespace boost { (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } else if (op == check_functor_type_tag) { - const detail::sp_typeinfo& check_type - = *out_buffer.type.type; - if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) + if (*out_buffer.type.type == boost::typeindex::type_id()) out_buffer.obj_ptr = &in_buffer.data; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &BOOST_SP_TYPEID(Functor); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } @@ -389,14 +360,12 @@ namespace boost { delete f; out_buffer.obj_ptr = 0; } else if (op == check_functor_type_tag) { - const detail::sp_typeinfo& check_type - = *out_buffer.type.type; - if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) + if (*out_buffer.type.type == boost::typeindex::type_id()) out_buffer.obj_ptr = in_buffer.obj_ptr; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &BOOST_SP_TYPEID(Functor); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } @@ -431,7 +400,7 @@ namespace boost { typedef typename get_function_tag::type tag_type; switch (op) { case get_functor_type_tag: - out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; return; @@ -500,14 +469,12 @@ namespace boost { wrapper_allocator.deallocate(victim,1); out_buffer.obj_ptr = 0; } else if (op == check_functor_type_tag) { - const detail::sp_typeinfo& check_type - = *out_buffer.type.type; - if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) + if (*out_buffer.type.type == boost::typeindex::type_id()) out_buffer.obj_ptr = in_buffer.obj_ptr; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &BOOST_SP_TYPEID(Functor); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } @@ -534,7 +501,7 @@ namespace boost { typedef typename get_function_tag::type tag_type; switch (op) { case get_functor_type_tag: - out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); + out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; return; @@ -635,11 +602,11 @@ public: /** Determine if the function is empty (i.e., has no target). */ bool empty() const { return !vtable; } - /** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void) + /** Retrieve the type of the stored function object, or type_id() if this is empty. */ - const detail::sp_typeinfo& target_type() const + const boost::typeindex::type_info& target_type() const { - if (!vtable) return BOOST_SP_TYPEID(void); + if (!vtable) return boost::typeindex::type_id().type_info(); detail::function::function_buffer type; get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); @@ -652,7 +619,7 @@ public: if (!vtable) return 0; detail::function::function_buffer type_result; - type_result.type.type = &BOOST_SP_TYPEID(Functor); + type_result.type.type = &boost::typeindex::type_id().type_info(); type_result.type.const_qualified = is_const::value; type_result.type.volatile_qualified = is_volatile::value; get_vtable()->manager(functor, type_result, @@ -666,7 +633,7 @@ public: if (!vtable) return 0; detail::function::function_buffer type_result; - type_result.type.type = &BOOST_SP_TYPEID(Functor); + type_result.type.type = &boost::typeindex::type_id().type_info(); type_result.type.const_qualified = true; type_result.type.volatile_qualified = is_volatile::value; get_vtable()->manager(functor, type_result, @@ -893,7 +860,6 @@ namespace detail { } // end namespace boost #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL -#undef BOOST_FUNCTION_COMPARE_TYPE_ID #if defined(BOOST_MSVC) # pragma warning( pop ) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5a2dbad..f3f13c5 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -21,6 +21,8 @@ import testing ; : [ run libs/function/test/function_test.cpp : : : : lib_function_test ] + [ run libs/function/test/function_test.cpp : : : off : lib_function_test_no_rtti ] + [ run libs/function/test/function_n_test.cpp : : : : ] [ run libs/function/test/allocator_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ] From bde64bf9ebe7a05e7c56505ea33133bde0ccbad0 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 2 Apr 2016 14:59:57 +0300 Subject: [PATCH 02/11] Fix gcc 6 warnings about invoking placement new on a buffer of insufficient size. --- include/boost/function/function_base.hpp | 32 ++++++++++++------- include/boost/function/function_template.hpp | 33 ++++++++++---------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index c36b9e4..75a1598 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -41,7 +41,7 @@ # pragma warning( push ) # pragma warning( disable : 4793 ) // complaint about native code generation # pragma warning( disable : 4127 ) // "conditional expression is constant" -#endif +#endif #if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) # define BOOST_FUNCTION_TARGET_FIX(x) x @@ -68,7 +68,8 @@ namespace boost { union function_buffer { // For pointers to function objects - mutable void* obj_ptr; + typedef void* obj_ptr_t; + mutable obj_ptr_t obj_ptr; // For pointers to std::type_info objects struct type_t { @@ -82,7 +83,8 @@ namespace boost { } type; // For function pointers of all kinds - mutable void (*func_ptr)(); + typedef void (*func_ptr_t)(); + mutable func_ptr_t func_ptr; // For bound member pointers struct bound_memfunc_ptr_t { @@ -98,8 +100,16 @@ namespace boost { bool is_volatile_qualified; } obj_ref; + enum { + size1 = sizeof(obj_ptr_t) > sizeof(type_t) ? sizeof(obj_ptr_t) : sizeof(type_t), + size2 = size1 > sizeof(func_ptr_t) ? size1 : sizeof(func_ptr_t), + size3 = size2 > sizeof(bound_memfunc_ptr_t) ? size2 : sizeof(bound_memfunc_ptr_t), + size4 = size3 > sizeof(obj_ref_t) ? size3 : sizeof(obj_ref_t), + data_size = size4 + }; + // To relax aliasing constraints - mutable char data; + mutable char data[data_size]; }; /** @@ -277,28 +287,28 @@ namespace boost { { if (op == clone_functor_tag || op == move_functor_tag) { const functor_type* in_functor = - reinterpret_cast(&in_buffer.data); - new (reinterpret_cast(&out_buffer.data)) functor_type(*in_functor); + reinterpret_cast(in_buffer.data); + new (reinterpret_cast(out_buffer.data)) functor_type(*in_functor); if (op == move_functor_tag) { - functor_type* f = reinterpret_cast(&in_buffer.data); + functor_type* f = reinterpret_cast(in_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } } else if (op == destroy_functor_tag) { // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. - functor_type* f = reinterpret_cast(&out_buffer.data); + functor_type* f = reinterpret_cast(out_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } else if (op == check_functor_type_tag) { if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = &in_buffer.data; + out_buffer.obj_ptr = in_buffer.data; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.type.volatile_qualified = false; } } }; @@ -853,6 +863,6 @@ namespace detail { #if defined(BOOST_MSVC) # pragma warning( pop ) -#endif +#endif #endif // BOOST_FUNCTION_BASE_HEADER diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 211b81d..b2bb540 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -16,7 +16,7 @@ #if defined(BOOST_MSVC) # pragma warning( push ) # pragma warning( disable : 4127 ) // "conditional expression is constant" -#endif +#endif #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) @@ -132,7 +132,7 @@ namespace boost { { FunctionObj* f; if (function_allows_small_object_optimization::value) - f = reinterpret_cast(&function_obj_ptr.data); + f = reinterpret_cast(function_obj_ptr.data); else f = reinterpret_cast(function_obj_ptr.obj_ptr); return (*f)(BOOST_FUNCTION_ARGS); @@ -153,7 +153,7 @@ namespace boost { { FunctionObj* f; if (function_allows_small_object_optimization::value) - f = reinterpret_cast(&function_obj_ptr.data); + f = reinterpret_cast(function_obj_ptr.data); else f = reinterpret_cast(function_obj_ptr.obj_ptr); BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); @@ -209,7 +209,7 @@ namespace boost { { MemberPtr* f = - reinterpret_cast(&function_obj_ptr.data); + reinterpret_cast(function_obj_ptr.data); return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); } }; @@ -227,7 +227,7 @@ namespace boost { { MemberPtr* f = - reinterpret_cast(&function_obj_ptr.data); + reinterpret_cast(function_obj_ptr.data); BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); } }; @@ -569,7 +569,7 @@ namespace boost { void assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const { - new (reinterpret_cast(&functor.data)) FunctionObj(f); + new (reinterpret_cast(functor.data)) FunctionObj(f); } template void @@ -752,14 +752,14 @@ namespace boost { { this->assign_to_own(f); } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() { this->move_assign(f); } #endif - + ~BOOST_FUNCTION_FUNCTION() { clear(); } result_type operator()(BOOST_FUNCTION_PARMS) const @@ -840,12 +840,11 @@ namespace boost { BOOST_CATCH_END return *this; } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES // Move assignment from another BOOST_FUNCTION_FUNCTION BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) { - if (&f == this) return *this; @@ -925,7 +924,7 @@ namespace boost { template apply handler_type; - + typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::manager_type manager_type; @@ -960,7 +959,7 @@ namespace boost { BOOST_FUNCTION_TEMPLATE_ARGS, Allocator> handler_type; - + typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::manager_type manager_type; @@ -987,7 +986,7 @@ namespace boost { // has its function object allocated on the heap, move_assign will pass // its buffer to *this, and set the argument's buffer pointer to NULL. void move_assign(BOOST_FUNCTION_FUNCTION& f) - { + { if (&f == this) return; @@ -1098,7 +1097,7 @@ public: function(self_type&& f): base_type(static_cast(f)){} function(base_type&& f): base_type(static_cast(f)){} #endif - + self_type& operator=(const self_type& f) { self_type(f).swap(*this); @@ -1111,7 +1110,7 @@ public: self_type(static_cast(f)).swap(*this); return *this; } -#endif +#endif template #ifndef BOOST_NO_SFINAE @@ -1147,7 +1146,7 @@ public: self_type(static_cast(f)).swap(*this); return *this; } -#endif +#endif }; #undef BOOST_FUNCTION_PARTIAL_SPEC @@ -1187,4 +1186,4 @@ public: #if defined(BOOST_MSVC) # pragma warning( pop ) -#endif +#endif From 54988e8e91ac0272f9364ae1818f519621b18317 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 2 Apr 2016 17:31:22 +0300 Subject: [PATCH 03/11] Changed implementation to avoid calculating the size of the raw data buffer manually. Trim trailing spaces. --- include/boost/function/function_base.hpp | 204 +++++++++---------- include/boost/function/function_template.hpp | 82 ++++---- 2 files changed, 142 insertions(+), 144 deletions(-) diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 75a1598..21a0c0d 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -65,7 +65,7 @@ namespace boost { * object pointers, and a structure that resembles a bound * member function pointer. */ - union function_buffer + union function_buffer_members { // For pointers to function objects typedef void* obj_ptr_t; @@ -99,17 +99,15 @@ namespace boost { bool is_const_qualified; bool is_volatile_qualified; } obj_ref; + }; - enum { - size1 = sizeof(obj_ptr_t) > sizeof(type_t) ? sizeof(obj_ptr_t) : sizeof(type_t), - size2 = size1 > sizeof(func_ptr_t) ? size1 : sizeof(func_ptr_t), - size3 = size2 > sizeof(bound_memfunc_ptr_t) ? size2 : sizeof(bound_memfunc_ptr_t), - size4 = size3 > sizeof(obj_ref_t) ? size3 : sizeof(obj_ref_t), - data_size = size4 - }; + union function_buffer + { + // Type-specific union members + mutable function_buffer_members members; // To relax aliasing constraints - mutable char data[data_size]; + mutable char data[sizeof(function_buffer_members)]; }; /** @@ -176,42 +174,42 @@ namespace boost { struct reference_manager { static inline void - manage(const function_buffer& in_buffer, function_buffer& out_buffer, + manage(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { switch (op) { - case clone_functor_tag: - out_buffer.obj_ref = in_buffer.obj_ref; + case clone_functor_tag: + out_buffer.members.obj_ref = in_buffer.members.obj_ref; return; case move_functor_tag: - out_buffer.obj_ref = in_buffer.obj_ref; - in_buffer.obj_ref.obj_ptr = 0; + out_buffer.members.obj_ref = in_buffer.members.obj_ref; + in_buffer.members.obj_ref.obj_ptr = 0; return; case destroy_functor_tag: - out_buffer.obj_ref.obj_ptr = 0; + out_buffer.members.obj_ref.obj_ptr = 0; return; case check_functor_type_tag: { // Check whether we have the same type. We can add // cv-qualifiers, but we can't take them away. - if (*out_buffer.type.type == boost::typeindex::type_id() - && (!in_buffer.obj_ref.is_const_qualified - || out_buffer.type.const_qualified) - && (!in_buffer.obj_ref.is_volatile_qualified - || out_buffer.type.volatile_qualified)) - out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr; + if (*out_buffer.members.type.type == boost::typeindex::type_id() + && (!in_buffer.members.obj_ref.is_const_qualified + || out_buffer.members.type.const_qualified) + && (!in_buffer.members.obj_ref.is_volatile_qualified + || out_buffer.members.type.volatile_qualified)) + out_buffer.members.obj_ptr = in_buffer.members.obj_ref.obj_ptr; else - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } return; case get_functor_type_tag: - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified; - out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = in_buffer.members.obj_ref.is_const_qualified; + out_buffer.members.type.volatile_qualified = in_buffer.members.obj_ref.is_volatile_qualified; return; } } @@ -225,9 +223,9 @@ namespace boost { struct function_allows_small_object_optimization { BOOST_STATIC_CONSTANT - (bool, + (bool, value = ((sizeof(F) <= sizeof(function_buffer) && - (alignment_of::value + (alignment_of::value % alignment_of::value == 0)))); }; @@ -239,7 +237,7 @@ namespace boost { A(a) { } - + functor_wrapper(const functor_wrapper& f) : F(static_cast(f)), A(static_cast(f)) @@ -258,35 +256,35 @@ namespace boost { // Function pointers static inline void - manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, + manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag) - out_buffer.func_ptr = in_buffer.func_ptr; + out_buffer.members.func_ptr = in_buffer.members.func_ptr; else if (op == move_functor_tag) { - out_buffer.func_ptr = in_buffer.func_ptr; - in_buffer.func_ptr = 0; + out_buffer.members.func_ptr = in_buffer.members.func_ptr; + in_buffer.members.func_ptr = 0; } else if (op == destroy_functor_tag) - out_buffer.func_ptr = 0; + out_buffer.members.func_ptr = 0; else if (op == check_functor_type_tag) { - if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = &in_buffer.func_ptr; + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = &in_buffer.members.func_ptr; else - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; } } // Function objects that fit in the small-object buffer. static inline void - manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, + manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag || op == move_functor_tag) { - const functor_type* in_functor = + const functor_type* in_functor = reinterpret_cast(in_buffer.data); new (reinterpret_cast(out_buffer.data)) functor_type(*in_functor); @@ -301,14 +299,14 @@ namespace boost { (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } else if (op == check_functor_type_tag) { - if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = in_buffer.data; + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.data; else - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; } } }; @@ -321,7 +319,7 @@ namespace boost { // Function pointers static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, function_ptr_tag) { functor_manager_common::manage_ptr(in_buffer,out_buffer,op); @@ -329,15 +327,15 @@ namespace boost { // Function objects that fit in the small-object buffer. static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::true_) { functor_manager_common::manage_small(in_buffer,out_buffer,op); } - + // Function objects that require heap allocation static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { if (op == clone_functor_tag) { @@ -347,27 +345,27 @@ namespace boost { // jewillco: Changing this to static_cast because GCC 2.95.3 is // obsolete. const functor_type* f = - static_cast(in_buffer.obj_ptr); + static_cast(in_buffer.members.obj_ptr); functor_type* new_f = new functor_type(*f); - out_buffer.obj_ptr = new_f; + out_buffer.members.obj_ptr = new_f; } else if (op == move_functor_tag) { - out_buffer.obj_ptr = in_buffer.obj_ptr; - in_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor pointer type */ functor_type* f = - static_cast(out_buffer.obj_ptr); + static_cast(out_buffer.members.obj_ptr); delete f; - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else if (op == check_functor_type_tag) { - if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = in_buffer.obj_ptr; + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; else - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; } } @@ -375,7 +373,7 @@ namespace boost { // object can use the small-object optimization buffer or // whether we need to allocate it on the heap. static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, function_obj_tag) { manager(in_buffer, out_buffer, op, @@ -384,7 +382,7 @@ namespace boost { // For member pointers, we use the small-object optimization buffer. static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, member_ptr_tag) { manager(in_buffer, out_buffer, op, mpl::true_()); @@ -394,15 +392,15 @@ namespace boost { /* Dispatch to an appropriate manager based on whether we have a function pointer or a function object pointer. */ static inline void - manage(const function_buffer& in_buffer, function_buffer& out_buffer, + manage(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { typedef typename get_function_tag::type tag_type; switch (op) { case get_functor_type_tag: - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; return; default: @@ -420,7 +418,7 @@ namespace boost { // Function pointers static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, function_ptr_tag) { functor_manager_common::manage_ptr(in_buffer,out_buffer,op); @@ -428,15 +426,15 @@ namespace boost { // Function objects that fit in the small-object buffer. static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::true_) { functor_manager_common::manage_small(in_buffer,out_buffer,op); } - + // Function objects that require heap allocation static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { typedef functor_wrapper functor_wrapper_type; @@ -449,34 +447,34 @@ namespace boost { // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. const functor_wrapper_type* f = - static_cast(in_buffer.obj_ptr); + static_cast(in_buffer.members.obj_ptr); wrapper_allocator_type wrapper_allocator(static_cast(*f)); wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); wrapper_allocator.construct(copy, *f); // Get back to the original pointer type functor_wrapper_type* new_f = static_cast(copy); - out_buffer.obj_ptr = new_f; + out_buffer.members.obj_ptr = new_f; } else if (op == move_functor_tag) { - out_buffer.obj_ptr = in_buffer.obj_ptr; - in_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor_wrapper_type */ functor_wrapper_type* victim = - static_cast(in_buffer.obj_ptr); + static_cast(in_buffer.members.obj_ptr); wrapper_allocator_type wrapper_allocator(static_cast(*victim)); wrapper_allocator.destroy(victim); wrapper_allocator.deallocate(victim,1); - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else if (op == check_functor_type_tag) { - if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = in_buffer.obj_ptr; + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; else - out_buffer.obj_ptr = 0; + out_buffer.members.obj_ptr = 0; } else /* op == get_functor_type_tag */ { - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; } } @@ -484,7 +482,7 @@ namespace boost { // object can use the small-object optimization buffer or // whether we need to allocate it on the heap. static inline void - manager(const function_buffer& in_buffer, function_buffer& out_buffer, + manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, function_obj_tag) { manager(in_buffer, out_buffer, op, @@ -495,15 +493,15 @@ namespace boost { /* Dispatch to an appropriate manager based on whether we have a function pointer or a function object pointer. */ static inline void - manage(const function_buffer& in_buffer, function_buffer& out_buffer, + manage(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { typedef typename get_function_tag::type tag_type; switch (op) { case get_functor_type_tag: - out_buffer.type.type = &boost::typeindex::type_id().type_info(); - out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; return; default: @@ -581,8 +579,8 @@ namespace boost { */ struct vtable_base { - void (*manager)(const function_buffer& in_buffer, - function_buffer& out_buffer, + void (*manager)(const function_buffer& in_buffer, + function_buffer& out_buffer, functor_manager_operation_type op); }; } // end namespace function @@ -610,7 +608,7 @@ public: detail::function::function_buffer type; get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); - return *type.type.type; + return *type.members.type.type; } template @@ -619,12 +617,12 @@ public: if (!vtable) return 0; detail::function::function_buffer type_result; - type_result.type.type = &boost::typeindex::type_id().type_info(); - type_result.type.const_qualified = is_const::value; - type_result.type.volatile_qualified = is_volatile::value; - get_vtable()->manager(functor, type_result, + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = is_const::value; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, detail::function::check_functor_type_tag); - return static_cast(type_result.obj_ptr); + return static_cast(type_result.members.obj_ptr); } template @@ -633,14 +631,14 @@ public: if (!vtable) return 0; detail::function::function_buffer type_result; - type_result.type.type = &boost::typeindex::type_id().type_info(); - type_result.type.const_qualified = true; - type_result.type.volatile_qualified = is_volatile::value; - get_vtable()->manager(functor, type_result, + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = true; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, detail::function::check_functor_type_tag); // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. - return static_cast(type_result.obj_ptr); + return static_cast(type_result.members.obj_ptr); } template diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index b2bb540..82c81d7 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -97,7 +97,7 @@ namespace boost { static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { - FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); return f(BOOST_FUNCTION_ARGS); } }; @@ -114,7 +114,7 @@ namespace boost { BOOST_FUNCTION_PARMS) { - FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); } }; @@ -134,7 +134,7 @@ namespace boost { if (function_allows_small_object_optimization::value) f = reinterpret_cast(function_obj_ptr.data); else - f = reinterpret_cast(function_obj_ptr.obj_ptr); + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); return (*f)(BOOST_FUNCTION_ARGS); } }; @@ -155,7 +155,7 @@ namespace boost { if (function_allows_small_object_optimization::value) f = reinterpret_cast(function_obj_ptr.data); else - f = reinterpret_cast(function_obj_ptr.obj_ptr); + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); } }; @@ -171,8 +171,8 @@ namespace boost { BOOST_FUNCTION_PARMS) { - FunctionObj* f = - reinterpret_cast(function_obj_ptr.obj_ptr); + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); return (*f)(BOOST_FUNCTION_ARGS); } }; @@ -189,8 +189,8 @@ namespace boost { BOOST_FUNCTION_PARMS) { - FunctionObj* f = - reinterpret_cast(function_obj_ptr.obj_ptr); + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); } }; @@ -208,7 +208,7 @@ namespace boost { BOOST_FUNCTION_PARMS) { - MemberPtr* f = + MemberPtr* f = reinterpret_cast(function_obj_ptr.data); return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); } @@ -226,7 +226,7 @@ namespace boost { BOOST_FUNCTION_PARMS) { - MemberPtr* f = + MemberPtr* f = reinterpret_cast(function_obj_ptr.data); BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); } @@ -322,7 +322,7 @@ namespace boost { /* Given the tag returned by get_function_tag, retrieve the actual invoker that will be used for the given function - object. + object. Each specialization contains an "apply" nested class template that accepts the function object, return type, function @@ -513,21 +513,21 @@ namespace boost { private: // Function pointers template - bool + bool assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const { this->clear(functor); if (f) { // should be a reinterpret cast, but some compilers insist // on giving cv-qualifiers to free functions - functor.func_ptr = reinterpret_cast(f); + functor.members.func_ptr = reinterpret_cast(f); return true; } else { return false; } } template - bool + bool assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const { return assign_to(f,functor,function_ptr_tag()); @@ -566,13 +566,13 @@ namespace boost { // Function objects // Assign to a function object using the small object optimization template - void + void assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const { new (reinterpret_cast(functor.data)) FunctionObj(f); } template - void + void assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const { assign_functor(f,functor,mpl::true_()); @@ -580,13 +580,13 @@ namespace boost { // Assign to a function object allocated on the heap. template - void + void assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const { - functor.obj_ptr = new FunctionObj(f); + functor.members.obj_ptr = new FunctionObj(f); } template - void + void assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const { typedef functor_wrapper functor_wrapper_type; @@ -597,15 +597,15 @@ namespace boost { wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); wrapper_allocator.construct(copy, functor_wrapper_type(f,a)); functor_wrapper_type* new_f = static_cast(copy); - functor.obj_ptr = new_f; + functor.members.obj_ptr = new_f; } template - bool + bool assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const { if (!boost::detail::function::has_empty_target(boost::addressof(f))) { - assign_functor(f, functor, + assign_functor(f, functor, mpl::bool_<(function_allows_small_object_optimization::value)>()); return true; } else { @@ -613,7 +613,7 @@ namespace boost { } } template - bool + bool assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const { if (!boost::detail::function::has_empty_target(boost::addressof(f))) { @@ -627,18 +627,18 @@ namespace boost { // Reference to a function object template - bool - assign_to(const reference_wrapper& f, + bool + assign_to(const reference_wrapper& f, function_buffer& functor, function_obj_ref_tag) const { - functor.obj_ref.obj_ptr = (void *)(f.get_pointer()); - functor.obj_ref.is_const_qualified = is_const::value; - functor.obj_ref.is_volatile_qualified = is_volatile::value; + functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer()); + functor.members.obj_ref.is_const_qualified = is_const::value; + functor.members.obj_ref.is_volatile_qualified = is_volatile::value; return true; } template - bool - assign_to_a(const reference_wrapper& f, + bool + assign_to_a(const reference_wrapper& f, function_buffer& functor, Allocator, function_obj_ref_tag) const { return assign_to(f,functor,function_obj_ref_tag()); @@ -921,7 +921,7 @@ namespace boost { typedef typename boost::detail::function::get_function_tag::type tag; typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; typedef typename get_invoker:: - template apply handler_type; @@ -932,7 +932,7 @@ namespace boost { // static initialization. Otherwise, we will have a race // condition here in multi-threaded code. See // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. - static const vtable_type stored_vtable = + static const vtable_type stored_vtable = { { &manager_type::manage }, &invoker_type::invoke }; if (stored_vtable.assign_to(f, functor)) { @@ -943,7 +943,7 @@ namespace boost { boost::detail::function::function_allows_small_object_optimization::value) value |= static_cast(0x01); vtable = reinterpret_cast(value); - } else + } else vtable = 0; } @@ -955,7 +955,7 @@ namespace boost { typedef typename boost::detail::function::get_function_tag::type tag; typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; typedef typename get_invoker:: - template apply_a handler_type; @@ -970,7 +970,7 @@ namespace boost { static const vtable_type stored_vtable = { { &manager_type::manage }, &invoker_type::invoke }; - if (stored_vtable.assign_to_a(f, functor, a)) { + if (stored_vtable.assign_to_a(f, functor, a)) { std::size_t value = reinterpret_cast(&stored_vtable.base); // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). if (boost::has_trivial_copy_constructor::value && @@ -978,14 +978,14 @@ namespace boost { boost::detail::function::function_allows_small_object_optimization::value) value |= static_cast(0x01); vtable = reinterpret_cast(value); - } else + } else vtable = 0; } - // Moves the value from the specified argument to *this. If the argument - // has its function object allocated on the heap, move_assign will pass - // its buffer to *this, and set the argument's buffer pointer to NULL. - void move_assign(BOOST_FUNCTION_FUNCTION& f) + // Moves the value from the specified argument to *this. If the argument + // has its function object allocated on the heap, move_assign will pass + // its buffer to *this, and set the argument's buffer pointer to NULL. + void move_assign(BOOST_FUNCTION_FUNCTION& f) { if (&f == this) return; @@ -1139,7 +1139,7 @@ public: self_type(f).swap(*this); return *this; } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES self_type& operator=(base_type&& f) { From 21ad529e1020fa7a75873621c546c426f804c13b Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 7 Oct 2016 23:07:34 -0500 Subject: [PATCH 04/11] Add, and update, documentation build targets. --- doc/Jamfile.v2 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index a0f5e0d..f3b8d67 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -14,3 +14,12 @@ boostbook function-doc pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html ; +############################################################################### +alias boostdoc + : function.xml + : + : + : ; +explicit boostdoc ; +alias boostrelease ; +explicit boostrelease ; From c326d30f2875a21da60b476e331f39b779755abd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 6 Nov 2016 14:43:42 +0200 Subject: [PATCH 05/11] Remove std::unary/binary_function use, they have been removed in C++17 --- include/boost/function/function_template.hpp | 11 ------ test/Jamfile.v2 | 2 + test/result_arg_types_test.cpp | 40 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 test/result_arg_types_test.cpp diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 82c81d7..7984c83 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -656,17 +656,6 @@ namespace boost { BOOST_FUNCTION_TEMPLATE_PARMS > class BOOST_FUNCTION_FUNCTION : public function_base - -#if BOOST_FUNCTION_NUM_ARGS == 1 - - , public std::unary_function - -#elif BOOST_FUNCTION_NUM_ARGS == 2 - - , public std::binary_function - -#endif - { public: #ifndef BOOST_NO_VOID_RETURNS diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f3f13c5..6f3cd0b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -66,6 +66,8 @@ import testing ; [ run libs/function/test/rvalues_test.cpp : : : : ] [ compile libs/function/test/function_typeof_test.cpp ] + + [ run libs/function/test/result_arg_types_test.cpp ] ; } diff --git a/test/result_arg_types_test.cpp b/test/result_arg_types_test.cpp new file mode 100644 index 0000000..33ccddc --- /dev/null +++ b/test/result_arg_types_test.cpp @@ -0,0 +1,40 @@ +// Boost.Function library + +// Copyright 2016 Peter Dimov + +// Use, modification and distribution is subject to +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +struct X +{ +}; + +struct Y +{ +}; + +struct Z +{ +}; + +int main() +{ + typedef boost::function F1; + + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + + typedef boost::function F2; + + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + + return boost::report_errors(); +} From fa2d6be8de606d2f73d02c9d93e74b4ce2eef188 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 17:15:26 +0200 Subject: [PATCH 06/11] Add .travis.yml --- .travis.yml | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8187005 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,57 @@ +# Copyright 2016 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +language: cpp + +sudo: false + +os: + - linux + - osx + +branches: + only: + - master + - develop + +install: + - cd .. + - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + - cd boost-root + - git submodule init libs/assert + - git submodule init libs/bind + - git submodule init libs/config + - git submodule init libs/core + - git submodule init libs/detail + - git submodule init libs/exception + - git submodule init libs/integer + - git submodule init libs/iterator + - git submodule init libs/lambda + - git submodule init libs/move + - git submodule init libs/mpl + - git submodule init libs/predef + - git submodule init libs/preprocessor + - git submodule init libs/smart_ptr + - git submodule init libs/static_assert + - git submodule init libs/test + - git submodule init libs/throw_exception + - git submodule init libs/tuple + - git submodule init libs/type_index + - git submodule init libs/type_traits + - git submodule init libs/typeof + - git submodule init libs/utility + - git submodule init tools/build + - git submodule update --depth 1 + - cp -r $TRAVIS_BUILD_DIR/* libs/function + - ./bootstrap.sh + - ./b2 headers + +script: + - TOOLSET=gcc,clang + - if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi + - ./b2 libs/function/test toolset=$TOOLSET + +notifications: + email: + on_success: always From 3a9161a44ec401b4f23caa56cf77114437e71ecd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 17:35:47 +0200 Subject: [PATCH 07/11] Add libs/timer to .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8187005..be16c4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ install: - git submodule init libs/static_assert - git submodule init libs/test - git submodule init libs/throw_exception + - git submodule init libs/timer - git submodule init libs/tuple - git submodule init libs/type_index - git submodule init libs/type_traits From fe093c72469e03a77902235127b61236dad2e7ba Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 17:47:14 +0200 Subject: [PATCH 08/11] Add timer dependencies to .travis.yml --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index be16c4c..c5431ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,19 +21,24 @@ install: - cd boost-root - git submodule init libs/assert - git submodule init libs/bind + - git submodule init libs/chrono - git submodule init libs/config - git submodule init libs/core - git submodule init libs/detail - git submodule init libs/exception - git submodule init libs/integer + - git submodule init libs/io - git submodule init libs/iterator - git submodule init libs/lambda - git submodule init libs/move - git submodule init libs/mpl - git submodule init libs/predef - git submodule init libs/preprocessor + - git submodule init libs/ratio + - git submodule init libs/rational - git submodule init libs/smart_ptr - git submodule init libs/static_assert + - git submodule init libs/system - git submodule init libs/test - git submodule init libs/throw_exception - git submodule init libs/timer @@ -42,6 +47,7 @@ install: - git submodule init libs/type_traits - git submodule init libs/typeof - git submodule init libs/utility + - git submodule init libs/winapi - git submodule init tools/build - git submodule update --depth 1 - cp -r $TRAVIS_BUILD_DIR/* libs/function From ec2efa53bab6b9b3eac1adf5772e2d811c081408 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 18:23:07 +0200 Subject: [PATCH 09/11] Add libs/align to .ravis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c5431ea..0f94ede 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ install: - cd .. - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root - cd boost-root + - git submodule init libs/align - git submodule init libs/assert - git submodule init libs/bind - git submodule init libs/chrono From 53b1ee6a751c3c9a2025ccb0da7caad28473d5ac Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 18:40:03 +0200 Subject: [PATCH 10/11] Add numeric/conversion to .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 0f94ede..d0e9134 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ install: - git submodule init libs/lambda - git submodule init libs/move - git submodule init libs/mpl + - git submodule init libs/numeric/conversion - git submodule init libs/predef - git submodule init libs/preprocessor - git submodule init libs/ratio From 2df73bc0245b6f48d42f5a73a8fe856870a8e157 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Nov 2016 19:48:01 +0200 Subject: [PATCH 11/11] Add the remaining dependencies to .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index d0e9134..fbd0db9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ install: - cd .. - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root - cd boost-root + - git submodule init libs/algorithm - git submodule init libs/align - git submodule init libs/assert - git submodule init libs/bind @@ -36,11 +37,13 @@ install: - git submodule init libs/numeric/conversion - git submodule init libs/predef - git submodule init libs/preprocessor + - git submodule init libs/range - git submodule init libs/ratio - git submodule init libs/rational - git submodule init libs/smart_ptr - git submodule init libs/static_assert - git submodule init libs/system + - git submodule init libs/optional - git submodule init libs/test - git submodule init libs/throw_exception - git submodule init libs/timer