Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:10:14

0001 // Boost.TypeErasure library
0002 //
0003 // Copyright 2011 Steven Watanabe
0004 //
0005 // Distributed under the Boost Software License Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // $Id$
0010 
0011 #ifndef BOOST_TYPE_ERASURE_PARAM_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_PARAM_HPP_INCLUDED
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/utility/enable_if.hpp>
0016 #include <boost/type_traits/is_same.hpp>
0017 #include <boost/type_traits/add_const.hpp>
0018 #include <boost/type_traits/remove_cv.hpp>
0019 #include <boost/type_traits/remove_reference.hpp>
0020 #include <boost/mpl/bool.hpp>
0021 #include <boost/mpl/if.hpp>
0022 #include <boost/type_erasure/detail/access.hpp>
0023 #include <boost/type_erasure/detail/storage.hpp>
0024 #include <boost/type_erasure/is_placeholder.hpp>
0025 #include <boost/type_erasure/concept_of.hpp>
0026 
0027 namespace boost {
0028 namespace type_erasure {
0029     
0030 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0031 
0032 template<class Concept, class T>
0033 class any;
0034     
0035 template<class Concept>
0036 class binding;
0037 
0038 #endif
0039 
0040 namespace detail {
0041 
0042 struct access;
0043 
0044 }
0045 
0046 namespace detail {
0047 
0048 template<class From, class To>
0049 struct placeholder_conversion : boost::mpl::false_ {};
0050 template<class T>
0051 struct placeholder_conversion<T, T> : boost::mpl::true_ {};
0052 template<class T>
0053 struct placeholder_conversion<T, T&> : boost::mpl::true_ {};
0054 template<class T>
0055 struct placeholder_conversion<T, const T&> : boost::mpl::true_ {};
0056 template<class T>
0057 struct placeholder_conversion<const T, T> : boost::mpl::true_ {};
0058 template<class T>
0059 struct placeholder_conversion<const T, const T&> : boost::mpl::true_ {};
0060 template<class T>
0061 struct placeholder_conversion<T&, T> : boost::mpl::true_ {};
0062 template<class T>
0063 struct placeholder_conversion<T&, T&> : boost::mpl::true_ {};
0064 template<class T>
0065 struct placeholder_conversion<T&, const T&> : boost::mpl::true_ {};
0066 template<class T>
0067 struct placeholder_conversion<const T&, T> : boost::mpl::true_ {};
0068 template<class T>
0069 struct placeholder_conversion<const T&, const T&> : boost::mpl::true_ {};
0070 
0071 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0072 template<class T>
0073 struct placeholder_conversion<T&&, T> : boost::mpl::true_ {};
0074 template<class T>
0075 struct placeholder_conversion<T&&, const T&> : boost::mpl::true_ {};
0076 template<class T>
0077 struct placeholder_conversion<T&&, T&&> : boost::mpl::true_ {};
0078 #endif
0079 
0080 }
0081 
0082 /**
0083  * \brief A wrapper to help with overload resolution for functions
0084  * operating on an @ref any.
0085  *
0086  * The template arguments are interpreted in
0087  * the same way as @ref any.
0088  *
0089  * A parameter of type @ref param can be initialized
0090  * with an @ref any that has the same @c Concept
0091  * and base placeholder when there exists a corresponding
0092  * standard conversion for the placeholder.
0093  * A conversion sequence from @ref any "any<C, P>" to @ref param "param<C, P1>" is
0094  * a better conversion sequence than @ref any "any<C, P>" to @ref param "param<C, P2>"
0095  * iff the corresponding placeholder standard conversion
0096  * sequence from P to P1 is a better conversion sequence than
0097  * P to P2.
0098  *
0099  * \note Overloading based on cv-qualifiers and rvalue-ness is
0100  * only supported in C++11.  In C++03, all conversion sequences
0101  * from @ref any to @ref param have the same rank.
0102  *
0103  * Example:
0104  *
0105  * \code
0106  * void f(param<C, _a&>);
0107  * void f(param<C, const _a&>);
0108  * void g(param<C, const _a&>);
0109  * void g(param<C, _a&&>);
0110  *
0111  * any<C, _a> a;
0112  * f(any<C, _a>()); // calls void f(param<C, const _a&>);
0113  * f(a);            // calls void f(param<C, _a&>); (ambiguous in C++03)
0114  * g(any<C, _a>()); // calls void g(param<C, _a&&>); (ambiguous in C++03)
0115  * g(a);            // calls void g(param<C, const _a&>);
0116  * \endcode
0117  *
0118  */
0119 template<class Concept, class T>
0120 class param {
0121 public:
0122 
0123     friend struct boost::type_erasure::detail::access;
0124 
0125     /** INTERNAL ONLY */
0126     typedef void _boost_type_erasure_is_any;
0127     /** INTERNAL ONLY */
0128     typedef param _boost_type_erasure_derived_type;
0129 
0130     template<class U>
0131     param(any<Concept, U>& a
0132 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0133         , typename boost::enable_if<
0134             ::boost::type_erasure::detail::placeholder_conversion<U, T>
0135         >::type* = 0
0136 #endif
0137         )
0138       : _impl(a)
0139     {}
0140     template<class U>
0141     param(const any<Concept, U>& a
0142 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0143         , typename boost::enable_if<
0144             ::boost::type_erasure::detail::placeholder_conversion<
0145                 typename ::boost::add_const<U>::type,
0146                 T
0147             >
0148         >::type* = 0
0149 #endif
0150         )
0151       : _impl(a)
0152     {}
0153 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0154     template<class U>
0155     param(any<Concept, U>&& a
0156 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0157         , typename boost::enable_if<
0158             ::boost::type_erasure::detail::placeholder_conversion<
0159                 U&&,
0160                 T
0161             >
0162         >::type* = 0
0163 #endif
0164         )
0165       : _impl(std::move(a))
0166     {}
0167 #endif
0168 
0169     /** INTERNAL ONLY */
0170     param(const ::boost::type_erasure::detail::storage& data,
0171           const ::boost::type_erasure::binding<Concept>& table)
0172       : _impl(data, table)
0173     {}
0174 
0175     /** Returns the stored @ref any. */
0176     any<Concept, T> get() const { return _impl; }
0177 private:
0178     any<Concept, T> _impl;
0179 };
0180 
0181 #if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) && !defined(BOOST_TYPE_ERASURE_DOXYGEN)
0182 
0183 template<class Concept, class T>
0184 class param<Concept, const T&> {
0185 public:
0186 
0187     friend struct boost::type_erasure::detail::access;
0188 
0189     /** INTERNAL ONLY */
0190     typedef void _boost_type_erasure_is_any;
0191     /** INTERNAL ONLY */
0192     typedef param _boost_type_erasure_derived_type;
0193 
0194     param(const ::boost::type_erasure::detail::storage& data,
0195           const ::boost::type_erasure::binding<Concept>& table)
0196       : _impl(data, table)
0197     {}
0198     template<class U>
0199     param(U& u, typename boost::enable_if< ::boost::is_same<U, const any<Concept, T> > >::type* = 0) : _impl(u) {}
0200     any<Concept, const T&> get() const { return _impl; }
0201 protected:
0202     struct _impl_t {
0203         _impl_t(const ::boost::type_erasure::detail::storage& data_,
0204               const ::boost::type_erasure::binding<Concept>& table_)
0205           : table(table_), data(data_)
0206         {}
0207         _impl_t(const any<Concept, T>& u)
0208           : table(::boost::type_erasure::detail::access::table(u)),
0209             data(::boost::type_erasure::detail::access::data(u))
0210         {}
0211         // It's safe to capture the table by reference, because
0212         // the user's argument should out-live us.  storage is
0213         // just a void*, so we don't need to add indirection.
0214         const ::boost::type_erasure::binding<Concept>& table;
0215         ::boost::type_erasure::detail::storage data;
0216     } _impl;
0217 };
0218 
0219 template<class Concept, class T>
0220 class param<Concept, T&> : public param<Concept, const T&> {
0221 public:
0222 
0223     friend struct boost::type_erasure::detail::access;
0224 
0225     /** INTERNAL ONLY */
0226     typedef void _boost_type_erasure_is_any;
0227     /** INTERNAL ONLY */
0228     typedef param _boost_type_erasure_derived_type;
0229 
0230     param(const ::boost::type_erasure::detail::storage& data,
0231           const ::boost::type_erasure::binding<Concept>& table)
0232       : param<Concept, const T&>(data, table)
0233     {}
0234     any<Concept, T&> get() const
0235     {
0236         return any<Concept, T&>(
0237             ::boost::type_erasure::detail::access::data(this->_impl),
0238             ::boost::type_erasure::detail::access::table(this->_impl));
0239     }
0240 };
0241 
0242 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0243 
0244 template<class Concept, class T>
0245 class param<Concept, T&&> : public param<Concept, const T&> {
0246 public:
0247 
0248     friend struct boost::type_erasure::detail::access;
0249 
0250     /** INTERNAL ONLY */
0251     typedef void _boost_type_erasure_is_any;
0252     /** INTERNAL ONLY */
0253     typedef param _boost_type_erasure_derived_type;
0254 
0255     param(const ::boost::type_erasure::detail::storage& data,
0256           const ::boost::type_erasure::binding<Concept>& table)
0257       : param<Concept, const T&>(data, table)
0258     {}
0259     any<Concept, T&&> get() const
0260     {
0261         return any<Concept, T&&>(
0262             ::boost::type_erasure::detail::access::data(this->_impl),
0263             ::boost::type_erasure::detail::access::table(this->_impl));
0264     }
0265 };
0266 
0267 #endif
0268 
0269 #endif
0270 
0271 /**
0272  * \brief Metafunction that creates a @ref param.
0273  *
0274  * If @c T is a (cv/reference qualified) placeholder,
0275  * returns @ref param<@ref concept_of "concept_of<Any>::type", T>,
0276  * otherwise, returns T.  This metafunction is intended
0277  * to be used for function arguments in specializations of
0278  * @ref concept_interface.
0279  *
0280  * \see derived, rebind_any
0281  */
0282 template<class Any, class T>
0283 struct as_param {
0284 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
0285     typedef detail::unspecified type;
0286 #else
0287     typedef typename ::boost::mpl::if_<
0288         ::boost::type_erasure::is_placeholder<
0289             typename ::boost::remove_cv<
0290                 typename ::boost::remove_reference<T>::type>::type>,
0291         param<typename ::boost::type_erasure::concept_of<Any>::type, T>,
0292         T
0293     >::type type;
0294 #endif
0295 };
0296 
0297 #ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
0298 
0299 template<class Any, class T>
0300 using as_param_t = typename ::boost::type_erasure::as_param<Any, T>::type;
0301 
0302 #endif
0303 
0304 }
0305 }
0306 
0307 #endif