#ifndef BOOST_REF_HPP_INCLUDED # define BOOST_REF_HPP_INCLUDED # if _MSC_VER+0 >= 1020 # pragma once # endif # include # include # include # include // // ref.hpp - ref/cref, useful helper functions // // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) // Copyright (C) 2001, 2002 Peter Dimov // Copyright (C) 2002 David Abrahams // Copyright (C) 2003 Doug Gregor // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // // See http://www.boost.org/libs/bind/ref.html for documentation. // namespace boost { struct deduce_ref_result {}; namespace detail { namespace ref { // ------ has_result_type --- template type_traits::yes_type has_result_type_helper(type*); template type_traits::no_type has_result_type_helper(...); template struct has_result_type { BOOST_STATIC_CONSTANT(bool, value = (sizeof(has_result_type_helper(0)) == sizeof(type_traits::yes_type))); }; // ------ has_argument_type --- template type_traits::yes_type has_argument_type_helper(type*); template type_traits::no_type has_argument_type_helper(...); template struct has_argument_type { BOOST_STATIC_CONSTANT(bool, value = (sizeof(has_argument_type_helper(0)) == sizeof(type_traits::yes_type))); }; // ------ has_first_and_second_argument_types --- template type_traits::yes_type has_first_and_second_argument_types_helper( type*, type*); template type_traits::no_type has_first_and_second_argument_types_helper(...); template struct has_first_and_second_argument_types { BOOST_STATIC_CONSTANT(bool, value = (sizeof(has_first_and_second_argument_types_helper(0, 0)) == sizeof(type_traits::yes_type))); }; // ------ has_argN_type --- template struct has_argN_type { BOOST_STATIC_CONSTANT(bool, value = false); }; #define BOOST_REF_HAS_ARGN_TYPE(N) \ template \ type_traits::yes_type \ has_arg##N##_type_helper(type*); \ \ template type_traits::no_type has_arg##N##_type_helper(...); \ \ template \ struct has_arg##N##_type \ { \ BOOST_STATIC_CONSTANT(bool, \ value = (sizeof(has_arg##N##_type_helper(0)) \ == sizeof(type_traits::yes_type))); \ }; \ \ template \ struct has_argN_type \ { \ BOOST_STATIC_CONSTANT(bool, value = (has_arg##N##_type::value)); \ }; BOOST_REF_HAS_ARGN_TYPE(1) BOOST_REF_HAS_ARGN_TYPE(2) BOOST_REF_HAS_ARGN_TYPE(3) BOOST_REF_HAS_ARGN_TYPE(4) BOOST_REF_HAS_ARGN_TYPE(5) BOOST_REF_HAS_ARGN_TYPE(6) BOOST_REF_HAS_ARGN_TYPE(7) BOOST_REF_HAS_ARGN_TYPE(8) BOOST_REF_HAS_ARGN_TYPE(9) BOOST_REF_HAS_ARGN_TYPE(10) #undef BOOST_REF_HAS_ARGN_TYPE // ------ get_result_type0 --- template struct get_result_type0_impl; template struct get_result_type0_impl { typedef typename T::result_type type; }; template struct get_result_type0_impl { typedef void type; }; template struct get_result_type0 : public get_result_type0_impl<(has_result_type::value), T> { }; // ------ get_result_type1 --- template struct get_result_type1_impl; template struct get_result_type1_impl { typedef typename T::result_type type; }; template struct get_result_type1_impl { typedef typename T::template sig::type type; }; template struct get_result_type1 : public get_result_type1_impl<(has_result_type::value), T, T1> {}; // ------ get_result_type2 --- template struct get_result_type2_impl; template struct get_result_type2_impl { typedef typename T::result_type type; }; template struct get_result_type2_impl { typedef typename T::template sig::type type; }; template struct get_result_type2 : public get_result_type2_impl<(has_result_type::value), T, T1, T2> {}; // ------ get_result_type3 --- template struct get_result_type3_impl; template struct get_result_type3_impl { typedef typename T::result_type type; }; template struct get_result_type3_impl { typedef typename T::template sig::type type; }; template struct get_result_type3 : public get_result_type3_impl<(has_result_type::value), T, T1, T2, T3> {}; // ------ get_result_type --- template struct get_result_type { typedef Result type; }; template struct get_result_type { typedef typename Deducer::type type; }; // ------ reference_wrapper_base template class reference_wrapper_base { public: operator T& () const { return *(this->t_); } T& get() const { return *(this->t_); } T* get_pointer() const { return this->t_; } typename get_result_type >::type operator()() const { return get()(); } protected: #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) explicit reference_wrapper_base(T& t) : t_(&t) {} #else explicit reference_wrapper_base(T& t) : t_(addressof(t)) {} #endif private: T* t_; }; // ------ reference_wrapper_with_first_and_second_argument_types template class reference_wrapper_with_first_and_second_argument_types : public reference_wrapper_base { typedef reference_wrapper_base inherited; protected: explicit reference_wrapper_with_first_and_second_argument_types(T& t) : inherited(t) {} public: typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type; using inherited::operator(); typename get_result_type >::type operator()(const first_argument_type& a1, const second_argument_type& a2) const { return this->get()(a1, a2); } }; // ------ reference_wrapper_with_argument_type template class maybe_also_first_and_second_argument_types; template class maybe_also_first_and_second_argument_types : public reference_wrapper_with_first_and_second_argument_types { typedef reference_wrapper_with_first_and_second_argument_types inherited; protected: explicit maybe_also_first_and_second_argument_types(T& t) : inherited(t) {} public: using inherited::operator(); }; template class maybe_also_first_and_second_argument_types : public reference_wrapper_base { typedef reference_wrapper_base inherited; protected: explicit maybe_also_first_and_second_argument_types(T& t) : inherited(t) {} public: using inherited::operator(); }; template class reference_wrapper_with_argument_type : public maybe_also_first_and_second_argument_types< T, Result, (has_first_and_second_argument_types::value)> { typedef maybe_also_first_and_second_argument_types< T, Result, (has_first_and_second_argument_types::value)> inherited; protected: explicit reference_wrapper_with_argument_type(T& t) : inherited(t) {} public: typedef typename T::argument_type argument_type; using inherited::operator(); typename get_result_type >::type operator()(const argument_type& a1) const { return this->get()(a1); } }; // ------ reference_wrapper_with_argN_types template class reference_wrapper_with_argN_types_impl; template class reference_wrapper_with_argN_types : public reference_wrapper_with_argN_types_impl::value)> { typedef reference_wrapper_with_argN_types_impl::value)> inherited; protected: explicit reference_wrapper_with_argN_types(T& t) : inherited(t) {} }; template class reference_wrapper_with_argN_types_impl : public reference_wrapper_with_argN_types { typedef reference_wrapper_with_argN_types inherited; protected: explicit reference_wrapper_with_argN_types_impl(T& t) : inherited(t) {} public: typedef typename T::arg1_type arg1_type; using inherited::operator(); typename get_result_type >::type operator()(arg1_type a1) const { return this->get()(a1); } }; template class reference_wrapper_with_argN_types_impl : public reference_wrapper_with_argN_types { typedef reference_wrapper_with_argN_types inherited; protected: explicit reference_wrapper_with_argN_types_impl(T& t) : inherited(t) {} public: typedef typename T::arg1_type arg1_type; typedef typename T::arg2_type arg2_type; using inherited::operator(); typename get_result_type >::type operator()(arg1_type a1, arg2_type a2) const { return this->get()(a1, a2); } }; template class reference_wrapper_with_argN_types_impl : public reference_wrapper_with_argN_types { typedef reference_wrapper_with_argN_types inherited; protected: explicit reference_wrapper_with_argN_types_impl(T& t) : inherited(t) {} public: typedef typename T::arg1_type arg1_type; typedef typename T::arg2_type arg2_type; typedef typename T::arg3_type arg3_type; using inherited::operator(); typename get_result_type >::type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const { return this->get()(a1, a2, a3); } }; // Passed the number of arguments we know how to handle template class reference_wrapper_with_argN_types_impl : public reference_wrapper_base { typedef reference_wrapper_base inherited; protected: explicit reference_wrapper_with_argN_types_impl(T& t) : inherited(t) {} public: using inherited::operator(); }; // Underlying function object does not have any more argument types template class reference_wrapper_with_argN_types_impl : public reference_wrapper_base { typedef reference_wrapper_base inherited; protected: explicit reference_wrapper_with_argN_types_impl(T& t) : inherited(t) {} public: using inherited::operator(); }; // ------ reference_wrapper_with_deduced_args template class reference_wrapper_with_deduced_args : public reference_wrapper_base { typedef reference_wrapper_base inherited; protected: explicit reference_wrapper_with_deduced_args(T& t) : inherited(t) {} public: using inherited::operator(); template typename get_result_type >::type operator()(T1& a1) const { return this->get()(a1); } template typename get_result_type >::type operator()(T1& a1, T2& a2) const { return this->get()(a1, a2); } template typename get_result_type >::type operator()(T1& a1, T2& a2, T3& a3) const { return this->get()(a1, a2, a3); } }; // ------ reference_wrapper_operators template class maybe_with_first_and_second_argument_types; template class maybe_with_first_and_second_argument_types : public reference_wrapper_with_first_and_second_argument_types { typedef reference_wrapper_with_first_and_second_argument_types inherited; protected: explicit maybe_with_first_and_second_argument_types(T& t) : inherited(t) {} }; template class maybe_with_first_and_second_argument_types : public reference_wrapper_with_deduced_args { typedef reference_wrapper_with_deduced_args inherited; protected: explicit maybe_with_first_and_second_argument_types(T& t) : inherited(t) {} }; template class maybe_with_argument_type; template class maybe_with_argument_type : public reference_wrapper_with_argument_type { typedef reference_wrapper_with_argument_type inherited; protected: explicit maybe_with_argument_type(T& t) : inherited(t) {} }; template class maybe_with_argument_type : public maybe_with_first_and_second_argument_types< T, Result, (has_first_and_second_argument_types::value)> { typedef maybe_with_first_and_second_argument_types< T, Result, (has_first_and_second_argument_types::value)> inherited; protected: explicit maybe_with_argument_type(T& t) : inherited(t) {} }; template class maybe_with_argN_types; template class maybe_with_argN_types : public reference_wrapper_with_argN_types { typedef reference_wrapper_with_argN_types inherited; protected: explicit maybe_with_argN_types(T& t) : inherited(t) {} }; template class maybe_with_argN_types : public maybe_with_argument_type::value)> { typedef maybe_with_argument_type::value)> inherited; protected: explicit maybe_with_argN_types(T& t) : inherited(t) {} }; template class reference_wrapper_operators : public maybe_with_argN_types::value)> { typedef maybe_with_argN_types::value)> inherited; protected: explicit reference_wrapper_operators(T& t) : inherited(t) {} }; } } // end namespace detail::ref template class reference_wrapper : public detail::ref::reference_wrapper_operators { typedef detail::ref::reference_wrapper_operators inherited; public: typedef T type; explicit reference_wrapper(T& t) : inherited(t) {} }; # if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570) # define BOOST_REF_CONST # else # define BOOST_REF_CONST const # endif template inline reference_wrapper BOOST_REF_CONST ref(T & t) { return reference_wrapper(t); } template inline reference_wrapper BOOST_REF_CONST cref(T const & t) { return reference_wrapper(t); } template inline reference_wrapper BOOST_REF_CONST ref(T & t) { return reference_wrapper(t); } template inline reference_wrapper BOOST_REF_CONST cref(T const & t) { return reference_wrapper(t); } # undef BOOST_REF_CONST # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template class is_reference_wrapper { public: BOOST_STATIC_CONSTANT(bool, value = false); }; template class is_reference_wrapper > { public: BOOST_STATIC_CONSTANT(bool, value = true); }; template class unwrap_reference { public: typedef T type; }; template class unwrap_reference > { public: typedef T type; }; # else // no partial specialization } // namespace boost namespace boost { namespace detail { typedef char (&yes_reference_wrapper_t)[1]; typedef char (&no_reference_wrapper_t)[2]; no_reference_wrapper_t is_reference_wrapper_test(...); template yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper >); template struct reference_unwrapper { template struct apply { typedef T type; }; }; template<> struct reference_unwrapper { template struct apply { typedef typename T::type type; }; }; } template class is_reference_wrapper { public: BOOST_STATIC_CONSTANT( bool, value = ( sizeof(detail::is_reference_wrapper_test(type())) == sizeof(detail::yes_reference_wrapper_t))); }; template class unwrap_reference : public detail::reference_unwrapper< is_reference_wrapper::value >::template apply {}; # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION } // namespace boost #endif // #ifndef BOOST_REF_HPP_INCLUDED