File indexing completed on 2025-01-31 10:02:38
0001
0002
0003
0004
0005
0006
0007
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
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
0081
0082
0083
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 , Iterator )
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
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