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_OPERATORS_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_OPERATORS_HPP_INCLUDED
0013 
0014 #include <iosfwd>
0015 #include <boost/utility/enable_if.hpp>
0016 #include <boost/type_erasure/detail/const.hpp>
0017 #include <boost/type_erasure/call.hpp>
0018 #include <boost/type_erasure/concept_interface.hpp>
0019 #include <boost/type_erasure/placeholder.hpp>
0020 #include <boost/type_erasure/concept_of.hpp>
0021 #include <boost/type_erasure/derived.hpp>
0022 #include <boost/type_erasure/rebind_any.hpp>
0023 #include <boost/type_erasure/param.hpp>
0024 #include <boost/type_erasure/check_match.hpp>
0025 #include <boost/type_erasure/relaxed.hpp>
0026 #include <boost/type_erasure/typeid_of.hpp>
0027 
0028 namespace boost {
0029 namespace type_erasure {
0030 
0031 /** INTERNAL ONLY */
0032 #define BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(name, op)                         \
0033     template<class T = _self>                                                       \
0034     struct name                                                                     \
0035     {                                                                               \
0036         static void apply(T& arg) { op arg; }                                       \
0037     };                                                                              \
0038                                                                                     \
0039     template<class T, class Base>                                                   \
0040     struct concept_interface<name<T>, Base, T,                                      \
0041         typename ::boost::enable_if<                                                \
0042             detail::should_be_non_const<T, Base>                                    \
0043         >::type                                                                     \
0044     > : Base                                                                        \
0045     {                                                                               \
0046         typedef typename ::boost::type_erasure::derived<Base>::type _derived;       \
0047         _derived& operator op()                                                     \
0048         {                                                                           \
0049             ::boost::type_erasure::call(name<T>(), *this);                          \
0050             return static_cast<_derived&>(*this);                                   \
0051         }                                                                           \
0052         typename ::boost::type_erasure::rebind_any<Base, T>::type operator op(int)  \
0053         {                                                                           \
0054             typename ::boost::type_erasure::rebind_any<Base, T>::type result(       \
0055                 static_cast<_derived&>(*this));                                     \
0056             ::boost::type_erasure::call(name<T>(), *this);                          \
0057             return result;                                                          \
0058         }                                                                           \
0059     };                                                                              \
0060                                                                                     \
0061     template<class T, class Base>                                                   \
0062     struct concept_interface<name<T>, Base, T,                                      \
0063         typename ::boost::enable_if<                                                \
0064             detail::should_be_const<T, Base>                                        \
0065         >::type                                                                     \
0066     > : Base                                                                        \
0067     {                                                                               \
0068         typedef typename ::boost::type_erasure::derived<Base>::type _derived;       \
0069         const _derived& operator op() const                                         \
0070         {                                                                           \
0071             ::boost::type_erasure::call(name<T>(), *this);                          \
0072             return static_cast<const _derived&>(*this);                             \
0073         }                                                                           \
0074         typename ::boost::type_erasure::rebind_any<Base, T>::type operator op(int) const \
0075         {                                                                           \
0076             typename ::boost::type_erasure::rebind_any<Base, T>::type result(       \
0077                 static_cast<const _derived&>(*this));                               \
0078             ::boost::type_erasure::call(name<T>(), *this);                          \
0079             return result;                                                          \
0080         }                                                                           \
0081     };
0082 
0083 /**
0084  * The @ref incrementable concept allow pre and
0085  * post increment on an @ref any.  The contained
0086  * type must provide a pre-increment operator.
0087  */
0088 BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(incrementable, ++)
0089 /**
0090  * The @ref decrementable concept allow pre and
0091  * post decrement on an @ref any.  The contained
0092  * type must provide a pre-decrement operator.
0093  */
0094 BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(decrementable, --)
0095 
0096 #undef BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR
0097 
0098 /** INTERNAL ONLY */
0099 #define BOOST_TYPE_ERASURE_UNARY_OPERATOR(name, op)                                     \
0100     template<class T = _self, class R = T>                                              \
0101     struct name                                                                         \
0102     {                                                                                   \
0103         static R apply(const T& arg) { return op arg; }                                 \
0104     };                                                                                  \
0105                                                                                         \
0106     template<class T, class R, class Base>                                              \
0107     struct concept_interface<name<T, R>, Base, T> : Base                                \
0108     {                                                                                   \
0109         typename ::boost::type_erasure::rebind_any<Base, R>::type operator op() const   \
0110         {                                                                               \
0111             return ::boost::type_erasure::call(name<T, R>(), *this);                    \
0112         }                                                                               \
0113     };
0114 
0115 /**
0116  * The @ref complementable concept allow use of the bitwise
0117  * complement operator on an @ref any.
0118  */
0119 BOOST_TYPE_ERASURE_UNARY_OPERATOR(complementable, ~)
0120 /**
0121  * The @ref negatable concept allow use of the unary
0122  * minus operator on an @ref any.
0123  */
0124 BOOST_TYPE_ERASURE_UNARY_OPERATOR(negatable, -)
0125 
0126 #undef BOOST_TYPE_ERASURE_UNARY_OPERATOR
0127 
0128 template<class R, class T = _self>
0129 struct dereferenceable
0130 {
0131     static R apply(const T& arg) { return *arg; }
0132 };
0133 
0134 /// \cond show_operators
0135 
0136 template<class R, class T, class Base>
0137 struct concept_interface<dereferenceable<R, T>, Base, T> : Base
0138 {
0139     typename ::boost::type_erasure::rebind_any<Base, R>::type operator*() const
0140     {
0141         return ::boost::type_erasure::call(dereferenceable<R, T>(), *this);
0142     }
0143 };
0144 
0145 /// \endcond
0146 
0147 /** INTERNAL ONLY */
0148 #define BOOST_TYPE_ERASURE_BINARY_OPERATOR(name, op)                        \
0149     template<class T = _self, class U = T, class R = T>                     \
0150     struct name                                                             \
0151     {                                                                       \
0152         static R apply(const T& lhs, const U& rhs) { return lhs op rhs; }   \
0153     };                                                                      \
0154                                                                             \
0155     template<class T, class U, class R, class Base>                         \
0156     struct concept_interface<name<T, U, R>, Base, T> : Base                 \
0157     {                                                                       \
0158         friend typename rebind_any<Base, R>::type                           \
0159         operator op(const typename derived<Base>::type& lhs,                \
0160                     typename as_param<Base, const U&>::type rhs)            \
0161         {                                                                   \
0162             return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs);  \
0163         }                                                                   \
0164     };                                                                      \
0165                                                                             \
0166     template<class T, class U, class R, class Base>                         \
0167     struct concept_interface<                                               \
0168         name<T, U, R>,                                                      \
0169         Base,                                                               \
0170         U,                                                                  \
0171         typename ::boost::disable_if<                                       \
0172             ::boost::type_erasure::is_placeholder<T> >::type                \
0173     > : Base                                                                \
0174     {                                                                       \
0175         friend typename rebind_any<Base, R>::type                           \
0176         operator op(const T& lhs,                                           \
0177                     const typename derived<Base>::type& rhs)                \
0178         {                                                                   \
0179             return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs);  \
0180         }                                                                   \
0181     };
0182 
0183 BOOST_TYPE_ERASURE_BINARY_OPERATOR(addable, +)
0184 BOOST_TYPE_ERASURE_BINARY_OPERATOR(subtractable, -)
0185 BOOST_TYPE_ERASURE_BINARY_OPERATOR(multipliable, *)
0186 BOOST_TYPE_ERASURE_BINARY_OPERATOR(dividable, /)
0187 BOOST_TYPE_ERASURE_BINARY_OPERATOR(modable, %)
0188 BOOST_TYPE_ERASURE_BINARY_OPERATOR(left_shiftable, <<)
0189 BOOST_TYPE_ERASURE_BINARY_OPERATOR(right_shiftable, >>)
0190 BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitandable, &)
0191 BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitorable, |)
0192 BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitxorable, ^)
0193 
0194 #undef BOOST_TYPE_ERASURE_BINARY_OPERATOR
0195 
0196 /** INTERNAL ONLY */
0197 #define BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(name, op)                    \
0198     template<class T = _self, class U = T>                                  \
0199     struct name                                                             \
0200     {                                                                       \
0201         static void apply(T& lhs, const U& rhs) { lhs op rhs; }             \
0202     };                                                                      \
0203                                                                             \
0204     template<class T, class U, class Base>                                  \
0205     struct concept_interface<name<T, U>, Base, T,                           \
0206         typename ::boost::disable_if<                                       \
0207             ::boost::is_same<                                               \
0208                 typename ::boost::type_erasure::placeholder_of<Base>::type, \
0209                 const T&                                                    \
0210             >                                                               \
0211         >::type                                                             \
0212     > : Base                                                                \
0213     {                                                                       \
0214         friend typename detail::non_const_this_param<Base>::type&           \
0215         operator op(typename detail::non_const_this_param<Base>::type& lhs, \
0216                     typename as_param<Base, const U&>::type rhs)            \
0217         {                                                                   \
0218             ::boost::type_erasure::call(name<T, U>(),lhs, rhs);             \
0219             return lhs;                                                     \
0220         }                                                                   \
0221     };                                                                      \
0222                                                                             \
0223     template<class T, class U, class Base>                                  \
0224     struct concept_interface<                                               \
0225         name<T, U>,                                                         \
0226         Base,                                                               \
0227         U,                                                                  \
0228         typename ::boost::disable_if<                                       \
0229             ::boost::type_erasure::is_placeholder<T> >::type                \
0230     > : Base                                                                \
0231     {                                                                       \
0232         friend T&                                                           \
0233         operator op(T& lhs, const typename derived<Base>::type& rhs)        \
0234         {                                                                   \
0235             ::boost::type_erasure::call(name<T, U>(),lhs, rhs);             \
0236             return lhs;                                                     \
0237         }                                                                   \
0238     };
0239 
0240 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(add_assignable, +=)
0241 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(subtract_assignable, -=)
0242 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(multiply_assignable, *=)
0243 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(divide_assignable, /=)
0244 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(mod_assignable, %=)
0245 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(left_shift_assignable, <<=)
0246 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(right_shift_assignable, >>=)
0247 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitand_assignable, &=)
0248 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitor_assignable, |=)
0249 BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitxor_assignable, ^=)
0250 
0251 #undef BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR
0252 
0253 template<class T = _self, class U = T>
0254 struct equality_comparable
0255 {
0256     static bool apply(const T& lhs, const U& rhs) { return lhs == rhs; }
0257 };
0258 
0259 /// \cond show_operators
0260 
0261 template<class T, class U, class Base>
0262 struct concept_interface<equality_comparable<T, U>, Base, T> : Base
0263 {
0264     friend bool operator==(const typename derived<Base>::type& lhs,
0265                            typename as_param<Base, const U&>::type rhs)
0266     {
0267         if(::boost::type_erasure::check_match(equality_comparable<T, U>(), lhs, rhs)) {
0268             return ::boost::type_erasure::unchecked_call(equality_comparable<T, U>(), lhs, rhs);
0269         } else {
0270             return false;
0271         }
0272     }
0273     friend bool operator!=(const typename derived<Base>::type& lhs,
0274                            typename as_param<Base, const U&>::type rhs)
0275     {
0276         return !(lhs == rhs);
0277     }
0278 };
0279 
0280 template<class T, class U, class Base>
0281 struct concept_interface<
0282     equality_comparable<T, U>,
0283     Base,
0284     U,
0285     typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<T> >::type
0286 > : Base
0287 {
0288     friend bool operator==(const T& lhs, const typename derived<Base>::type& rhs)
0289     {
0290         return ::boost::type_erasure::call(equality_comparable<T, U>(), lhs, rhs);
0291     }
0292     friend bool operator!=(const T& lhs, const typename derived<Base>::type& rhs)
0293     {
0294         return !(lhs == rhs);
0295     }
0296 };
0297 
0298 /// \endcond
0299 
0300 template<class T = _self, class U = T>
0301 struct less_than_comparable
0302 {
0303     static bool apply(const T& lhs, const U& rhs) { return lhs < rhs; }
0304 };
0305 
0306 namespace detail {
0307 
0308 template<class F, class T, class U>
0309 bool less_impl(const F& f, const T& lhs, const U& rhs, ::boost::mpl::true_)
0310 {
0311     if(::boost::type_erasure::check_match(f, lhs, rhs)) {
0312         return ::boost::type_erasure::unchecked_call(f, lhs, rhs);
0313     } else {
0314         return ::boost::type_erasure::typeid_of(
0315             static_cast<const typename derived<T>::type&>(lhs)
0316         ).before(
0317             ::boost::type_erasure::typeid_of(
0318                 static_cast<const typename derived<U>::type&>(rhs)
0319             )
0320         ) != false;
0321     }
0322 }
0323 
0324 template<class F, class T, class U>
0325 bool less_impl(const F& f, const T& lhs, const U& rhs, ::boost::mpl::false_)
0326 {
0327     return ::boost::type_erasure::call(f, lhs, rhs);
0328 }
0329 
0330 }
0331 
0332 /// \cond show_operators
0333 
0334 template<class T, class Base>
0335 struct concept_interface<less_than_comparable<T, T>, Base, T> : Base
0336 {
0337     friend bool operator<(const typename derived<Base>::type& lhs,
0338                           typename as_param<Base, const T&>::type rhs)
0339     {
0340         return ::boost::type_erasure::detail::less_impl(
0341             less_than_comparable<T, T>(),
0342             lhs, rhs,
0343             ::boost::type_erasure::is_relaxed<
0344                 typename ::boost::type_erasure::concept_of<Base>::type>());
0345     }
0346     friend bool operator>=(const typename derived<Base>::type& lhs,
0347                            typename as_param<Base, const T&>::type rhs)
0348     {
0349         return !(lhs < rhs);
0350     }
0351     friend bool operator>(typename as_param<Base, const T&>::type lhs,
0352                           const typename derived<Base>::type& rhs)
0353     {
0354         return rhs < lhs;
0355     }
0356     friend bool operator<=(typename as_param<Base, const T&>::type lhs,
0357                           const typename derived<Base>::type& rhs)
0358     {
0359         return !(rhs < lhs);
0360     }
0361 };
0362 
0363 template<class T, class U, class Base>
0364 struct concept_interface<less_than_comparable<T, U>, Base, T> : Base
0365 {
0366     friend bool operator<(const typename derived<Base>::type& lhs,
0367                           typename as_param<Base, const U&>::type rhs)
0368     {
0369         return ::boost::type_erasure::call(less_than_comparable<T, U>(), lhs, rhs);
0370     }
0371     friend bool operator>=(const typename derived<Base>::type& lhs,
0372                            typename as_param<Base, const U&>::type rhs)
0373     {
0374         return !(lhs < rhs);
0375     }
0376     friend bool operator>(typename as_param<Base, const U&>::type lhs,
0377                           const typename derived<Base>::type& rhs)
0378     {
0379         return rhs < lhs;
0380     }
0381     friend bool operator<=(typename as_param<Base, const U&>::type lhs,
0382                           const typename derived<Base>::type& rhs)
0383     {
0384         return !(rhs < lhs);
0385     }
0386 };
0387 
0388 template<class T, class U, class Base>
0389 struct concept_interface<
0390     less_than_comparable<T, U>,
0391     Base,
0392     U,
0393     typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<T> >::type
0394 > : Base
0395 {
0396     friend bool operator<(const T& lhs, const typename derived<Base>::type& rhs)
0397     {
0398         return ::boost::type_erasure::call(less_than_comparable<T, U>(), lhs, rhs);
0399     }
0400     friend bool operator>=(const T& lhs, const typename derived<Base>::type& rhs)
0401     {
0402         return !(lhs < rhs);
0403     }
0404     friend bool operator>(const typename derived<Base>::type& lhs, const T& rhs)
0405     {
0406         return rhs < lhs;
0407     }
0408     friend bool operator<=(const typename derived<Base>::type& lhs, const T& rhs)
0409     {
0410         return !(rhs < lhs);
0411     }
0412 };
0413 
0414 /// \endcond
0415 
0416 template<class R, class T = _self, class N = std::ptrdiff_t>
0417 struct subscriptable
0418 {
0419     static R apply(T& arg, const N& index) { return arg[index]; }
0420 };
0421 
0422 /// \cond show_operators
0423 
0424 template<class R, class T, class N, class Base>
0425 struct concept_interface<subscriptable<R, T, N>, Base, typename ::boost::remove_const<T>::type,
0426     typename ::boost::enable_if<
0427         ::boost::type_erasure::detail::should_be_non_const<T, Base>
0428     >::type
0429 > : Base
0430 {
0431     typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
0432         typename ::boost::type_erasure::as_param<Base, const N&>::type index)
0433     {
0434         return ::boost::type_erasure::call(subscriptable<R, T, N>(), *this, index);
0435     }
0436 };
0437 
0438 template<class R, class T, class N, class Base>
0439 struct concept_interface<subscriptable<R, T, N>, Base, typename ::boost::remove_const<T>::type,
0440     typename ::boost::enable_if<
0441         ::boost::type_erasure::detail::should_be_const<T, Base>
0442     >::type
0443 > : Base
0444 {
0445     typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
0446         typename ::boost::type_erasure::as_param<Base, const N&>::type index) const
0447     {
0448         return ::boost::type_erasure::call(subscriptable<R, const T, N>(), *this, index);
0449     }
0450 };
0451 
0452 /// \endcond
0453 
0454 /**
0455  * The @ref ostreamable concept allows an @ref any to be
0456  * written to a @c std::ostream.
0457  */
0458 template<class Os = std::ostream, class T = _self>
0459 struct ostreamable
0460 {
0461     static void apply(Os& out, const T& arg) { out << arg; }
0462 };
0463 
0464 /// \cond show_operators
0465 
0466 template<class Base, class Os, class T>
0467 struct concept_interface<ostreamable<Os, T>, Base, Os> : Base
0468 {
0469     friend typename detail::non_const_this_param<Base>::type&
0470     operator<<(typename detail::non_const_this_param<Base>::type& lhs,
0471                typename ::boost::type_erasure::as_param<Base, const T&>::type rhs)
0472     {
0473         ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
0474         return lhs;
0475     }
0476 };
0477 
0478 template<class Base, class Os, class T>
0479 struct concept_interface<
0480     ostreamable<Os, T>,
0481     Base,
0482     T,
0483     typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<Os> >::type
0484 > : Base
0485 {
0486     friend Os&
0487     operator<<(Os& lhs,
0488                const typename ::boost::type_erasure::derived<Base>::type& rhs)
0489     {
0490         ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
0491         return lhs;
0492     }
0493 };
0494 
0495 /// \endcond
0496 
0497 /**
0498  * The @ref istreamable concept allows an @ref any to be
0499  * read from a @c std::istream.
0500  */
0501 template<class Is = std::istream, class T = _self>
0502 struct istreamable
0503 {
0504     static void apply(Is& out, T& arg) { out >> arg; }
0505 };
0506 
0507 /// \cond show_operators
0508 
0509 
0510 template<class Base, class Is, class T>
0511 struct concept_interface<istreamable<Is, T>, Base, Is> : Base
0512 {
0513     friend typename detail::non_const_this_param<Base>::type&
0514     operator>>(typename detail::non_const_this_param<Base>::type& lhs,
0515                typename ::boost::type_erasure::as_param<Base, T&>::type rhs)
0516     {
0517         ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
0518         return lhs;
0519     }
0520 };
0521 
0522 template<class Base, class Is, class T>
0523 struct concept_interface<
0524     istreamable<Is, T>,
0525     Base,
0526     T,
0527     typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<Is> >::type
0528 > : Base
0529 {
0530     friend Is&
0531     operator>>(Is& lhs,
0532                typename ::boost::type_erasure::derived<Base>::type& rhs)
0533     {
0534         ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
0535         return lhs;
0536     }
0537 };
0538 
0539 /// \endcond
0540 
0541 }
0542 }
0543 
0544 #endif