annotate DEPENDENCIES/generic/include/boost/spirit/home/qi/detail/assign_to.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Joel de Guzman
Chris@16 3 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 4 http://spirit.sourceforge.net/
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM)
Chris@16 10 #define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM
Chris@16 11
Chris@16 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/spirit/home/qi/detail/construct.hpp>
Chris@16 17 #include <boost/spirit/home/support/unused.hpp>
Chris@16 18 #include <boost/spirit/home/qi/detail/attributes.hpp>
Chris@16 19 #include <boost/spirit/home/support/container.hpp>
Chris@16 20 #include <boost/fusion/include/copy.hpp>
Chris@16 21 #include <boost/ref.hpp>
Chris@16 22 #include <boost/range/iterator_range.hpp>
Chris@16 23
Chris@16 24 namespace boost { namespace spirit { namespace traits
Chris@16 25 {
Chris@16 26 ///////////////////////////////////////////////////////////////////////////
Chris@16 27 // This file contains assignment utilities. The utilities provided also
Chris@16 28 // accept spirit's unused_type; all no-ops. Compiler optimization will
Chris@16 29 // easily strip these away.
Chris@16 30 ///////////////////////////////////////////////////////////////////////////
Chris@16 31 namespace detail
Chris@16 32 {
Chris@16 33 template <typename T>
Chris@16 34 struct is_iter_range : mpl::false_ {};
Chris@16 35
Chris@16 36 template <typename I>
Chris@16 37 struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {};
Chris@16 38
Chris@16 39 template <typename C>
Chris@16 40 struct is_container_of_ranges
Chris@16 41 : is_iter_range<typename C::value_type> {};
Chris@16 42 }
Chris@16 43
Chris@16 44 template <typename Attribute, typename Iterator, typename Enable>
Chris@16 45 struct assign_to_attribute_from_iterators
Chris@16 46 {
Chris@16 47 // Common case
Chris@16 48 static void
Chris@16 49 call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_)
Chris@16 50 {
Chris@16 51 if (traits::is_empty(attr))
Chris@16 52 attr = Attribute(first, last);
Chris@16 53 else {
Chris@16 54 for (Iterator i = first; i != last; ++i)
Chris@16 55 push_back(attr, *i);
Chris@16 56 }
Chris@16 57 }
Chris@16 58
Chris@16 59 // If Attribute is a container with value_type==iterator_range<T> just push the
Chris@16 60 // iterator_range into it
Chris@16 61 static void
Chris@16 62 call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_)
Chris@16 63 {
Chris@16 64 typename Attribute::value_type rng(first, last);
Chris@16 65 push_back(attr, rng);
Chris@16 66 }
Chris@16 67
Chris@16 68 static void
Chris@16 69 call(Iterator const& first, Iterator const& last, Attribute& attr)
Chris@16 70 {
Chris@16 71 call(first, last, attr, detail::is_container_of_ranges<Attribute>());
Chris@16 72 }
Chris@16 73 };
Chris@16 74
Chris@16 75 template <typename Attribute, typename Iterator>
Chris@16 76 struct assign_to_attribute_from_iterators<
Chris@16 77 reference_wrapper<Attribute>, Iterator>
Chris@16 78 {
Chris@16 79 static void
Chris@16 80 call(Iterator const& first, Iterator const& last
Chris@16 81 , reference_wrapper<Attribute> attr)
Chris@16 82 {
Chris@16 83 if (traits::is_empty(attr))
Chris@16 84 attr = Attribute(first, last);
Chris@16 85 else {
Chris@16 86 for (Iterator i = first; i != last; ++i)
Chris@16 87 push_back(attr, *i);
Chris@16 88 }
Chris@16 89 }
Chris@16 90 };
Chris@16 91
Chris@16 92 template <typename Attribute, typename Iterator>
Chris@16 93 struct assign_to_attribute_from_iterators<
Chris@16 94 boost::optional<Attribute>, Iterator>
Chris@16 95 {
Chris@16 96 static void
Chris@16 97 call(Iterator const& first, Iterator const& last
Chris@16 98 , boost::optional<Attribute>& attr)
Chris@16 99 {
Chris@16 100 Attribute val;
Chris@16 101 assign_to(first, last, val);
Chris@16 102 attr = val;
Chris@16 103 }
Chris@16 104 };
Chris@16 105
Chris@16 106 template <typename Iterator>
Chris@16 107 struct assign_to_attribute_from_iterators<
Chris@16 108 iterator_range<Iterator>, Iterator>
Chris@16 109 {
Chris@16 110 static void
Chris@16 111 call(Iterator const& first, Iterator const& last
Chris@16 112 , iterator_range<Iterator>& attr)
Chris@16 113 {
Chris@16 114 attr = iterator_range<Iterator>(first, last);
Chris@16 115 }
Chris@16 116 };
Chris@16 117
Chris@16 118 template <typename Iterator, typename Attribute>
Chris@16 119 inline void
Chris@16 120 assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
Chris@16 121 {
Chris@16 122 assign_to_attribute_from_iterators<Attribute, Iterator>::
Chris@16 123 call(first, last, attr);
Chris@16 124 }
Chris@16 125
Chris@16 126 template <typename Iterator>
Chris@16 127 inline void
Chris@16 128 assign_to(Iterator const&, Iterator const&, unused_type)
Chris@16 129 {
Chris@16 130 }
Chris@16 131
Chris@16 132 ///////////////////////////////////////////////////////////////////////////
Chris@16 133 template <typename T, typename Attribute>
Chris@16 134 void assign_to(T const& val, Attribute& attr);
Chris@16 135
Chris@16 136 template <typename Attribute, typename T, typename Enable>
Chris@16 137 struct assign_to_attribute_from_value
Chris@16 138 {
Chris@16 139 typedef typename traits::one_element_sequence<Attribute>::type
Chris@16 140 is_one_element_sequence;
Chris@16 141
Chris@16 142 typedef typename mpl::eval_if<
Chris@16 143 is_one_element_sequence
Chris@16 144 , fusion::result_of::at_c<Attribute, 0>
Chris@16 145 , mpl::identity<Attribute&>
Chris@16 146 >::type type;
Chris@16 147
Chris@16 148 template <typename T_>
Chris@16 149 static void
Chris@16 150 call(T_ const& val, Attribute& attr, mpl::false_)
Chris@16 151 {
Chris@16 152 attr = static_cast<Attribute>(val);
Chris@16 153 }
Chris@16 154
Chris@16 155 // This handles the case where the attribute is a single element fusion
Chris@16 156 // sequence. We silently assign to the only element and treat it as the
Chris@16 157 // attribute to parse the results into.
Chris@16 158 template <typename T_>
Chris@16 159 static void
Chris@16 160 call(T_ const& val, Attribute& attr, mpl::true_)
Chris@16 161 {
Chris@16 162 typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
Chris@16 163 element_type;
Chris@16 164 fusion::at_c<0>(attr) = static_cast<element_type>(val);
Chris@16 165 }
Chris@16 166
Chris@16 167 static void
Chris@16 168 call(T const& val, Attribute& attr)
Chris@16 169 {
Chris@16 170 call(val, attr, is_one_element_sequence());
Chris@16 171 }
Chris@16 172 };
Chris@16 173
Chris@16 174 template <typename Attribute>
Chris@16 175 struct assign_to_attribute_from_value<Attribute, Attribute>
Chris@16 176 {
Chris@16 177 static void
Chris@16 178 call(Attribute const& val, Attribute& attr)
Chris@16 179 {
Chris@16 180 attr = val;
Chris@16 181 }
Chris@16 182 };
Chris@16 183
Chris@16 184 template <typename Attribute, typename T>
Chris@16 185 struct assign_to_attribute_from_value<Attribute, reference_wrapper<T>
Chris@16 186 , typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
Chris@16 187 {
Chris@16 188 static void
Chris@16 189 call(reference_wrapper<T> const& val, Attribute& attr)
Chris@16 190 {
Chris@16 191 assign_to(val.get(), attr);
Chris@16 192 }
Chris@16 193 };
Chris@16 194
Chris@16 195 template <typename Attribute, typename T>
Chris@16 196 struct assign_to_attribute_from_value<Attribute, boost::optional<T>
Chris@16 197 , typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
Chris@16 198 {
Chris@16 199 static void
Chris@16 200 call(boost::optional<T> const& val, Attribute& attr)
Chris@16 201 {
Chris@16 202 assign_to(val.get(), attr);
Chris@16 203 }
Chris@16 204 };
Chris@16 205
Chris@16 206 namespace detail
Chris@16 207 {
Chris@16 208 template <typename A, typename B>
Chris@16 209 struct is_same_size_sequence
Chris@16 210 : mpl::bool_<fusion::result_of::size<A>::value
Chris@16 211 == fusion::result_of::size<B>::value>
Chris@16 212 {};
Chris@16 213 }
Chris@16 214
Chris@16 215 template <typename Attribute, typename T>
Chris@16 216 struct assign_to_attribute_from_value<Attribute, T,
Chris@16 217 mpl::and_<
Chris@16 218 fusion::traits::is_sequence<Attribute>,
Chris@16 219 fusion::traits::is_sequence<T>,
Chris@16 220 detail::is_same_size_sequence<Attribute, T>
Chris@16 221 >
Chris@16 222 >
Chris@16 223 {
Chris@16 224 static void
Chris@16 225 call(T const& val, Attribute& attr)
Chris@16 226 {
Chris@16 227 fusion::copy(val, attr);
Chris@16 228 }
Chris@16 229 };
Chris@16 230
Chris@16 231 ///////////////////////////////////////////////////////////////////////////
Chris@16 232 template <typename Attribute, typename T, typename Enable>
Chris@16 233 struct assign_to_container_from_value
Chris@16 234 {
Chris@16 235 // T is not a container and not a string
Chris@16 236 template <typename T_>
Chris@16 237 static void call(T_ const& val, Attribute& attr, mpl::false_, mpl::false_)
Chris@16 238 {
Chris@16 239 traits::push_back(attr, val);
Chris@16 240 }
Chris@16 241
Chris@16 242 // T is a container (but not a string), and T is convertible to the
Chris@16 243 // value_type of the Attribute container
Chris@16 244 template <typename T_>
Chris@16 245 static void
Chris@16 246 append_to_container_not_string(T_ const& val, Attribute& attr, mpl::true_)
Chris@16 247 {
Chris@16 248 traits::push_back(attr, val);
Chris@16 249 }
Chris@16 250
Chris@16 251 // T is a container (but not a string), generic overload
Chris@16 252 template <typename T_>
Chris@16 253 static void
Chris@16 254 append_to_container_not_string(T_ const& val, Attribute& attr, mpl::false_)
Chris@16 255 {
Chris@16 256 typedef typename traits::container_iterator<T_ const>::type
Chris@16 257 iterator_type;
Chris@16 258
Chris@16 259 iterator_type end = traits::end(val);
Chris@16 260 for (iterator_type i = traits::begin(val); i != end; traits::next(i))
Chris@16 261 traits::push_back(attr, traits::deref(i));
Chris@16 262 }
Chris@16 263
Chris@16 264 // T is a container (but not a string)
Chris@16 265 template <typename T_>
Chris@16 266 static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
Chris@16 267 {
Chris@16 268 typedef typename container_value<Attribute>::type value_type;
Chris@16 269 typedef typename is_convertible<T, value_type>::type is_value_type;
Chris@16 270
Chris@16 271 append_to_container_not_string(val, attr, is_value_type());
Chris@16 272 }
Chris@16 273
Chris@16 274 ///////////////////////////////////////////////////////////////////////
Chris@16 275 // T is a string
Chris@16 276 template <typename Iterator>
Chris@16 277 static void append_to_string(Attribute& attr, Iterator begin, Iterator end)
Chris@16 278 {
Chris@16 279 for (Iterator i = begin; i != end; ++i)
Chris@16 280 traits::push_back(attr, *i);
Chris@16 281 }
Chris@16 282
Chris@16 283 // T is string, but not convertible to value_type of container
Chris@16 284 template <typename T_>
Chris@16 285 static void append_to_container(T_ const& val, Attribute& attr, mpl::false_)
Chris@16 286 {
Chris@16 287 typedef typename char_type_of<T_>::type char_type;
Chris@16 288
Chris@16 289 append_to_string(attr, traits::get_begin<char_type>(val)
Chris@16 290 , traits::get_end<char_type>(val));
Chris@16 291 }
Chris@16 292
Chris@16 293 // T is string, and convertible to value_type of container
Chris@16 294 template <typename T_>
Chris@16 295 static void append_to_container(T_ const& val, Attribute& attr, mpl::true_)
Chris@16 296 {
Chris@16 297 traits::push_back(attr, val);
Chris@16 298 }
Chris@16 299
Chris@16 300 template <typename T_, typename Pred>
Chris@16 301 static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
Chris@16 302 {
Chris@16 303 typedef typename container_value<Attribute>::type value_type;
Chris@16 304 typedef typename is_convertible<T, value_type>::type is_value_type;
Chris@16 305
Chris@16 306 append_to_container(val, attr, is_value_type());
Chris@16 307 }
Chris@16 308
Chris@16 309 ///////////////////////////////////////////////////////////////////////
Chris@16 310 static void call(T const& val, Attribute& attr)
Chris@16 311 {
Chris@16 312 typedef typename traits::is_container<T>::type is_container;
Chris@16 313 typedef typename traits::is_string<T>::type is_string;
Chris@16 314
Chris@16 315 call(val, attr, is_container(), is_string());
Chris@16 316 }
Chris@16 317 };
Chris@16 318
Chris@16 319 template <typename Attribute>
Chris@16 320 struct assign_to_container_from_value<Attribute, Attribute>
Chris@16 321 {
Chris@16 322 static void
Chris@16 323 call(Attribute const& val, Attribute& attr)
Chris@16 324 {
Chris@16 325 attr = val;
Chris@16 326 }
Chris@16 327 };
Chris@16 328
Chris@16 329 template <typename Attribute, typename T>
Chris@16 330 struct assign_to_container_from_value<Attribute, boost::optional<T>
Chris@16 331 , typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
Chris@16 332 {
Chris@16 333 static void
Chris@16 334 call(boost::optional<T> const& val, Attribute& attr)
Chris@16 335 {
Chris@16 336 assign_to(val.get(), attr);
Chris@16 337 }
Chris@16 338 };
Chris@16 339
Chris@16 340 template <typename Attribute, typename T>
Chris@16 341 struct assign_to_container_from_value<Attribute, reference_wrapper<T>
Chris@16 342 , typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
Chris@16 343 {
Chris@16 344 static void
Chris@16 345 call(reference_wrapper<T> const& val, Attribute& attr)
Chris@16 346 {
Chris@16 347 assign_to(val.get(), attr);
Chris@16 348 }
Chris@16 349 };
Chris@16 350
Chris@16 351 ///////////////////////////////////////////////////////////////////////////
Chris@16 352 namespace detail
Chris@16 353 {
Chris@16 354 // overload for non-container attributes
Chris@16 355 template <typename T, typename Attribute>
Chris@16 356 inline void
Chris@16 357 assign_to(T const& val, Attribute& attr, mpl::false_)
Chris@16 358 {
Chris@16 359 assign_to_attribute_from_value<Attribute, T>::call(val, attr);
Chris@16 360 }
Chris@16 361
Chris@16 362 // overload for containers (but not for variants or optionals
Chris@16 363 // holding containers)
Chris@16 364 template <typename T, typename Attribute>
Chris@16 365 inline void
Chris@16 366 assign_to(T const& val, Attribute& attr, mpl::true_)
Chris@16 367 {
Chris@16 368 assign_to_container_from_value<Attribute, T>::call(val, attr);
Chris@16 369 }
Chris@16 370 }
Chris@16 371
Chris@16 372 template <typename T, typename Attribute>
Chris@16 373 inline void
Chris@16 374 assign_to(T const& val, Attribute& attr)
Chris@16 375 {
Chris@16 376 typedef typename mpl::and_<
Chris@16 377 traits::is_container<Attribute>
Chris@16 378 , traits::not_is_variant<Attribute>
Chris@16 379 , traits::not_is_optional<Attribute>
Chris@16 380 >::type is_not_wrapped_container;
Chris@16 381
Chris@16 382 detail::assign_to(val, attr, is_not_wrapped_container());
Chris@16 383 }
Chris@16 384
Chris@16 385 template <typename T>
Chris@16 386 inline void
Chris@16 387 assign_to(T const&, unused_type)
Chris@16 388 {
Chris@16 389 }
Chris@16 390 }}}
Chris@16 391
Chris@16 392 #endif