Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:38

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004     http://spirit.sourceforge.net/
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #if !defined(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
0010 #define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
0011 
0012 #include <boost/fusion/support/category_of.hpp>
0013 #include <boost/spirit/home/x3/support/unused.hpp>
0014 #include <boost/fusion/include/deque.hpp>
0015 #include <boost/mpl/identity.hpp>
0016 #include <boost/type_traits/make_void.hpp>
0017 
0018 #include <vector>
0019 #include <string>
0020 #include <iterator>
0021 #include <algorithm>
0022 
0023 namespace boost { namespace spirit { namespace x3 { namespace traits
0024 {
0025     ///////////////////////////////////////////////////////////////////////////
0026     //  This file contains some container utils for stl containers.
0027     ///////////////////////////////////////////////////////////////////////////
0028 
0029     namespace detail
0030     {
0031         template <typename T, typename Enabler = void>
0032         struct is_container_impl : mpl::false_ {};
0033 
0034         template <typename T>
0035         struct is_container_impl<T, void_t<
0036             typename T::value_type, typename T::iterator,
0037             typename T::size_type, typename T::reference> > : mpl::true_ {};
0038 
0039         template <typename T, typename Enabler = void>
0040         struct is_associative_impl : mpl::false_ {};
0041 
0042         template <typename T>
0043         struct is_associative_impl<T, void_t<typename T::key_type>>
0044             : mpl::true_ {};
0045     }
0046 
0047     template <typename T>
0048     using is_container = typename detail::is_container_impl<T>::type;
0049 
0050     template <typename T>
0051     using is_associative = typename detail::is_associative_impl<T>::type;
0052 
0053     ///////////////////////////////////////////////////////////////////////////
0054     namespace detail
0055     {
0056         template <typename T>
0057         struct remove_value_const : mpl::identity<T> {};
0058 
0059         template <typename T>
0060         struct remove_value_const<T const> : remove_value_const<T> {};
0061 
0062         template <typename F, typename S>
0063         struct remove_value_const<std::pair<F, S>>
0064         {
0065             typedef typename remove_value_const<F>::type first_type;
0066             typedef typename remove_value_const<S>::type second_type;
0067             typedef std::pair<first_type, second_type> type;
0068         };
0069     }
0070 
0071     ///////////////////////////////////////////////////////////////////////
0072     template <typename Container, typename Enable = void>
0073     struct container_value
0074       : detail::remove_value_const<typename Container::value_type>
0075     {};
0076 
0077     template <typename Container>
0078     struct container_value<Container const> : container_value<Container> {};
0079 
0080     // There is no single container value for fusion maps, but because output
0081     // of this metafunc is used to check wheter parser's attribute can be
0082     // saved to container, we simply return whole fusion::map as is
0083     // so that check can be done in traits::is_substitute specialisation
0084     template <typename T>
0085     struct container_value<T
0086                , typename enable_if<typename mpl::eval_if <
0087                             fusion::traits::is_sequence<T>
0088                             , fusion::traits::is_associative<T>
0089                             , mpl::false_ >::type >::type>
0090     : mpl::identity<T> {};
0091 
0092     template <>
0093     struct container_value<unused_type> : mpl::identity<unused_type> {};
0094 
0095     ///////////////////////////////////////////////////////////////////////////
0096     template <typename Container, typename Enable = void>
0097     struct container_iterator
0098         : mpl::identity<typename Container::iterator> {};
0099 
0100     template <typename Container>
0101     struct container_iterator<Container const>
0102          : mpl::identity<typename Container::const_iterator> {};
0103 
0104     template <>
0105     struct container_iterator<unused_type>
0106         : mpl::identity<unused_type const*> {};
0107 
0108     template <>
0109     struct container_iterator<unused_type const>
0110         : mpl::identity<unused_type const*> {};
0111 
0112     ///////////////////////////////////////////////////////////////////////////
0113     template <typename Container, typename T>
0114     bool push_back(Container& c, T&& val);
0115 
0116     template <typename Container, typename Enable = void>
0117     struct push_back_container
0118     {
0119         template <typename T>
0120         static bool call(Container& c, T&& val)
0121         {
0122             c.insert(c.end(), static_cast<T&&>(val));
0123             return true;
0124         }
0125     };
0126 
0127     template <typename Container, typename T>
0128     inline bool push_back(Container& c, T&& val)
0129     {
0130         return push_back_container<Container>::call(c, static_cast<T&&>(val));
0131     }
0132 
0133     template <typename Container>
0134     inline bool push_back(Container&, unused_type)
0135     {
0136         return true;
0137     }
0138 
0139     template <typename T>
0140     inline bool push_back(unused_type, T&&)
0141     {
0142         return true;
0143     }
0144 
0145     inline bool push_back(unused_type, unused_type)
0146     {
0147         return true;
0148     }
0149 
0150     ///////////////////////////////////////////////////////////////////////////
0151     template <typename Container, typename Iterator>
0152     bool append(Container& c, Iterator first, Iterator last);
0153 
0154     template <typename Container, typename Enable = void>
0155     struct append_container
0156     {
0157     private:
0158         template <typename Iterator>
0159         static void insert(Container& c, Iterator first, Iterator last, mpl::false_)
0160         {
0161             c.insert(c.end(), first, last);
0162         }
0163 
0164         template <typename Iterator>
0165         static void insert(Container& c, Iterator first, Iterator last, mpl::true_)
0166         {
0167             c.insert(first, last);
0168         }
0169 
0170     public:
0171         template <typename Iterator>
0172         static bool call(Container& c, Iterator first, Iterator last)
0173         {
0174             insert(c, first, last, is_associative<Container>{});
0175             return true;
0176         }
0177     };
0178 
0179     template <typename Container, typename Iterator>
0180     inline bool append(Container& c, Iterator first, Iterator last)
0181     {
0182         return append_container<Container>::call(c, first, last);
0183     }
0184 
0185     template <typename Iterator>
0186     inline bool append(unused_type, Iterator /* first */, Iterator /* last */)
0187     {
0188         return true;
0189     }
0190 
0191     ///////////////////////////////////////////////////////////////////////////
0192     template <typename Container, typename Enable = void>
0193     struct is_empty_container
0194     {
0195         static bool call(Container const& c)
0196         {
0197             return c.empty();
0198         }
0199     };
0200 
0201     template <typename Container>
0202     inline bool is_empty(Container const& c)
0203     {
0204         return is_empty_container<Container>::call(c);
0205     }
0206 
0207     inline bool is_empty(unused_type)
0208     {
0209         return true;
0210     }
0211 
0212     ///////////////////////////////////////////////////////////////////////////
0213     template <typename Container, typename Enable = void>
0214     struct begin_container
0215     {
0216         static typename container_iterator<Container>::type call(Container& c)
0217         {
0218             return c.begin();
0219         }
0220     };
0221 
0222     template <typename Container>
0223     inline typename container_iterator<Container>::type
0224     begin(Container& c)
0225     {
0226         return begin_container<Container>::call(c);
0227     }
0228 
0229     inline unused_type const*
0230     begin(unused_type)
0231     {
0232         return &unused;
0233     }
0234 
0235     ///////////////////////////////////////////////////////////////////////////
0236     template <typename Container, typename Enable = void>
0237     struct end_container
0238     {
0239         static typename container_iterator<Container>::type call(Container& c)
0240         {
0241             return c.end();
0242         }
0243     };
0244 
0245     template <typename Container>
0246     inline typename container_iterator<Container>::type
0247     end(Container& c)
0248     {
0249         return end_container<Container>::call(c);
0250     }
0251 
0252     inline unused_type const*
0253     end(unused_type)
0254     {
0255         return &unused;
0256     }
0257 
0258 
0259     ///////////////////////////////////////////////////////////////////////////
0260     template <typename Iterator, typename Enable = void>
0261     struct deref_iterator
0262     {
0263         typedef typename std::iterator_traits<Iterator>::reference type;
0264         static type call(Iterator& it)
0265         {
0266             return *it;
0267         }
0268     };
0269 
0270     template <typename Iterator>
0271     typename deref_iterator<Iterator>::type
0272     deref(Iterator& it)
0273     {
0274         return deref_iterator<Iterator>::call(it);
0275     }
0276 
0277     inline unused_type
0278     deref(unused_type const*)
0279     {
0280         return unused;
0281     }
0282 
0283     ///////////////////////////////////////////////////////////////////////////
0284     template <typename Iterator, typename Enable = void>
0285     struct next_iterator
0286     {
0287         static void call(Iterator& it)
0288         {
0289             ++it;
0290         }
0291     };
0292 
0293     template <typename Iterator>
0294     void next(Iterator& it)
0295     {
0296         next_iterator<Iterator>::call(it);
0297     }
0298 
0299     inline void next(unused_type const*)
0300     {
0301         // do nothing
0302     }
0303 
0304     ///////////////////////////////////////////////////////////////////////////
0305     template <typename Iterator, typename Enable = void>
0306     struct compare_iterators
0307     {
0308         static bool call(Iterator const& it1, Iterator const& it2)
0309         {
0310             return it1 == it2;
0311         }
0312     };
0313 
0314     template <typename Iterator>
0315     bool compare(Iterator& it1, Iterator& it2)
0316     {
0317         return compare_iterators<Iterator>::call(it1, it2);
0318     }
0319 
0320     inline bool compare(unused_type const*, unused_type const*)
0321     {
0322         return false;
0323     }
0324 
0325     ///////////////////////////////////////////////////////////////////////////
0326     template <typename T>
0327     struct build_container : mpl::identity<std::vector<T>> {};
0328 
0329     template <typename T>
0330     struct build_container<boost::fusion::deque<T> > : build_container<T> {};
0331 
0332     template <>
0333     struct build_container<unused_type> : mpl::identity<unused_type> {};
0334 
0335     template <>
0336     struct build_container<char> : mpl::identity<std::string> {};
0337 
0338 }}}}
0339 
0340 #endif