Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:47:41

0001 /*=============================================================================
0002     Copyright (c) 2004 Angus Leeming
0003     Copyright (c) 2004 Joel de Guzman
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying 
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #ifndef BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
0009 #define BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
0010 
0011 #include <utility>
0012 #include <boost/mpl/eval_if.hpp>
0013 #include <boost/type_traits/is_same.hpp>
0014 #include <boost/type_traits/is_const.hpp>
0015 #include <boost/type_traits/is_convertible.hpp>
0016 
0017 namespace boost { namespace phoenix { namespace stl
0018 {
0019 ///////////////////////////////////////////////////////////////////////////////
0020 //
0021 //  Metafunctions "value_type_of", "key_type_of" etc.
0022 //
0023 //      These metafunctions define a typedef "type" that returns the nested
0024 //      type if it exists. If not then the typedef returns void.
0025 //
0026 //      For example, "value_type_of<std::vector<int> >::type" is "int" whilst
0027 //      "value_type_of<double>::type" is "void".
0028 //
0029 //      I use a macro to define structs "value_type_of" etc simply to cut
0030 //      down on the amount of code. The macro is #undef-ed immediately after
0031 //      its final use.
0032 //
0033 /////////////////////////////////////////////////////////////////c//////////////
0034 #define MEMBER_TYPE_OF(MEMBER_TYPE)                                             \
0035     template <typename C>                                                       \
0036     struct BOOST_PP_CAT(MEMBER_TYPE, _of)                                       \
0037     {                                                                           \
0038         typedef typename C::MEMBER_TYPE type;                                   \
0039     }
0040 
0041     MEMBER_TYPE_OF(allocator_type);
0042     MEMBER_TYPE_OF(const_iterator);
0043     MEMBER_TYPE_OF(const_reference);
0044     MEMBER_TYPE_OF(const_reverse_iterator);
0045     MEMBER_TYPE_OF(container_type);
0046     MEMBER_TYPE_OF(data_type);
0047     MEMBER_TYPE_OF(iterator);
0048     MEMBER_TYPE_OF(key_compare);
0049     MEMBER_TYPE_OF(key_type);
0050     MEMBER_TYPE_OF(reference);
0051     MEMBER_TYPE_OF(reverse_iterator);
0052     MEMBER_TYPE_OF(size_type);
0053     MEMBER_TYPE_OF(value_compare);
0054     MEMBER_TYPE_OF(value_type);
0055 
0056 #undef MEMBER_TYPE_OF
0057 
0058 ///////////////////////////////////////////////////////////////////////////////
0059 //
0060 //  Const-Qualified types.
0061 //
0062 //      Many of the stl member functions have const and non-const
0063 //      overloaded versions that return distinct types. For example:
0064 //
0065 //          iterator begin();
0066 //          const_iterator begin() const;
0067 //
0068 //      The three class templates defined below,
0069 //      const_qualified_reference_of, const_qualified_iterator_of
0070 //      and const_qualified_reverse_iterator_of provide a means to extract
0071 //      this return type automatically.
0072 //
0073 ///////////////////////////////////////////////////////////////////////////////
0074     template <typename C>
0075     struct const_qualified_reference_of
0076     {
0077         typedef typename
0078             boost::mpl::eval_if_c<
0079                 boost::is_const<C>::value
0080               , const_reference_of<C>
0081               , reference_of<C>
0082             >::type
0083         type;
0084     };
0085 
0086     template <typename C>
0087     struct const_qualified_iterator_of
0088     {
0089         typedef typename
0090             boost::mpl::eval_if_c<
0091                 boost::is_const<C>::value
0092               , const_iterator_of<C>
0093               , iterator_of<C>
0094             >::type
0095         type;
0096     };
0097 
0098     template <typename C>
0099     struct const_qualified_reverse_iterator_of
0100     {
0101         typedef typename
0102             boost::mpl::eval_if_c<
0103                 boost::is_const<C>::value
0104               , const_reverse_iterator_of<C>
0105               , reverse_iterator_of<C>
0106             >::type
0107         type;
0108     };
0109 
0110 ///////////////////////////////////////////////////////////////////////////////
0111 //
0112 //  has_mapped_type<C>
0113 //
0114 //      Given a container C, determine if it is a map, multimap, unordered_map,
0115 //      or unordered_multimap by checking if it has a member type named "mapped_type".
0116 //
0117 ///////////////////////////////////////////////////////////////////////////////
0118     namespace stl_impl
0119     {
0120         struct one { char a[1]; };
0121         struct two { char a[2]; };
0122 
0123         template <typename C>
0124         one has_mapped_type(typename C::mapped_type(*)());
0125 
0126         template <typename C>
0127         two has_mapped_type(...);
0128     }
0129 
0130     template <typename C>
0131     struct has_mapped_type
0132         : boost::mpl::bool_<
0133             sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one)
0134         >
0135     {};
0136 
0137 ///////////////////////////////////////////////////////////////////////////////
0138 //
0139 //  has_key_type<C>
0140 //
0141 //      Given a container C, determine if it is a Associative Container
0142 //      by checking if it has a member type named "key_type".
0143 //
0144 ///////////////////////////////////////////////////////////////////////////////
0145     namespace stl_impl
0146     {
0147         template <typename C>
0148         one has_key_type(typename C::key_type(*)());
0149 
0150         template <typename C>
0151         two has_key_type(...);
0152     }
0153 
0154     template <typename C>
0155     struct has_key_type
0156         : boost::mpl::bool_<
0157             sizeof(stl_impl::has_key_type<C>(0)) == sizeof(stl_impl::one)
0158         >
0159     {};
0160 
0161 ///////////////////////////////////////////////////////////////////////////////
0162 //
0163 //  is_key_type_of<C, Arg>
0164 //
0165 //      Lazy evaluation friendly predicate.
0166 //
0167 ///////////////////////////////////////////////////////////////////////////////
0168 
0169     template <typename C, typename Arg>
0170     struct is_key_type_of
0171         : boost::is_convertible<Arg, typename key_type_of<C>::type>
0172     {};
0173 
0174 ///////////////////////////////////////////////////////////////////////////////
0175 //
0176 //  map_insert_returns_pair<C>
0177 //
0178 //      Distinguish a map from a multimap by checking the return type
0179 //      of its "insert" member function. A map returns a pair while
0180 //      a multimap returns an iterator.
0181 //
0182 ///////////////////////////////////////////////////////////////////////////////
0183     namespace stl_impl
0184     {
0185         //  Cool implementation of map_insert_returns_pair by Daniel Wallin.
0186         //  Thanks Daniel!!! I owe you a Pizza!
0187 
0188         template<class A, class B>
0189         one map_insert_returns_pair_check(std::pair<A,B> const&);
0190 
0191         template <typename T>
0192         two map_insert_returns_pair_check(T const&);
0193 
0194         template <typename C>
0195         struct map_insert_returns_pair
0196         {
0197             static typename C::value_type const& get;
0198             BOOST_STATIC_CONSTANT(int,
0199                 value = sizeof(
0200                     map_insert_returns_pair_check(((C*)0)->insert(get))));
0201             typedef boost::mpl::bool_<value == sizeof(one)> type;
0202         };
0203     }
0204 
0205     template <typename C>
0206     struct map_insert_returns_pair
0207         : stl_impl::map_insert_returns_pair<C>::type {};
0208 
0209 }}} // namespace boost::phoenix::stl
0210 
0211 #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP