annotate DEPENDENCIES/generic/include/boost/spirit/home/karma/detail/extract_from.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 // Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 2 //
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #if !defined(BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM)
Chris@16 7 #define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM
Chris@16 8
Chris@16 9 #if defined(_MSC_VER)
Chris@16 10 #pragma once
Chris@16 11 #endif
Chris@16 12
Chris@16 13 #include <boost/spirit/include/phoenix_core.hpp>
Chris@16 14 #include <boost/spirit/home/support/unused.hpp>
Chris@16 15 #include <boost/spirit/home/support/attributes_fwd.hpp>
Chris@16 16 #include <boost/spirit/home/karma/detail/attributes.hpp>
Chris@16 17 #include <boost/spirit/home/support/container.hpp>
Chris@16 18
Chris@16 19 #include <boost/ref.hpp>
Chris@16 20 #include <boost/optional.hpp>
Chris@16 21
Chris@16 22 ///////////////////////////////////////////////////////////////////////////////
Chris@16 23 namespace boost { namespace spirit { namespace traits
Chris@16 24 {
Chris@16 25 ///////////////////////////////////////////////////////////////////////////
Chris@16 26 // This file contains attribute extraction utilities. The utilities
Chris@16 27 // provided also accept spirit's unused_type; all no-ops. Compiler
Chris@16 28 // optimization will easily strip these away.
Chris@16 29 ///////////////////////////////////////////////////////////////////////////
Chris@16 30
Chris@16 31 namespace detail
Chris@16 32 {
Chris@16 33 ///////////////////////////////////////////////////////////////////////
Chris@16 34 // extract first and second element of a fusion sequence
Chris@16 35 template <typename T>
Chris@16 36 struct add_const_ref
Chris@16 37 : add_reference<typename add_const<T>::type>
Chris@16 38 {};
Chris@16 39
Chris@16 40 template <typename T, int N>
Chris@16 41 struct value_at_c
Chris@16 42 : add_const_ref<typename fusion::result_of::value_at_c<T, N>::type>
Chris@16 43 {};
Chris@16 44 }
Chris@16 45
Chris@16 46 // This is the default case: the plain attribute values
Chris@16 47 template <typename Attribute, typename Exposed, typename Enable/*= void*/>
Chris@16 48 struct extract_from_attribute
Chris@16 49 {
Chris@16 50 typedef typename traits::one_element_sequence<Attribute>::type
Chris@16 51 is_one_element_sequence;
Chris@16 52
Chris@16 53 typedef typename mpl::eval_if<
Chris@16 54 is_one_element_sequence
Chris@16 55 , detail::value_at_c<Attribute, 0>
Chris@16 56 , mpl::identity<Attribute const&>
Chris@16 57 >::type type;
Chris@16 58
Chris@16 59 template <typename Context>
Chris@16 60 static type call(Attribute const& attr, Context&, mpl::false_)
Chris@16 61 {
Chris@16 62 return attr;
Chris@16 63 }
Chris@16 64
Chris@16 65 // This handles the case where the attribute is a single element fusion
Chris@16 66 // sequence. We silently extract the only element and treat it as the
Chris@16 67 // attribute to generate output from.
Chris@16 68 template <typename Context>
Chris@16 69 static type call(Attribute const& attr, Context& ctx, mpl::true_)
Chris@16 70 {
Chris@16 71 return extract_from<Exposed>(fusion::at_c<0>(attr), ctx);
Chris@16 72 }
Chris@16 73
Chris@16 74 template <typename Context>
Chris@16 75 static type call(Attribute const& attr, Context& ctx)
Chris@16 76 {
Chris@16 77 return call(attr, ctx, is_one_element_sequence());
Chris@16 78 }
Chris@16 79 };
Chris@16 80
Chris@16 81 // This handles optional attributes.
Chris@16 82 template <typename Attribute, typename Exposed>
Chris@16 83 struct extract_from_attribute<boost::optional<Attribute>, Exposed>
Chris@16 84 {
Chris@16 85 typedef Attribute const& type;
Chris@16 86
Chris@16 87 template <typename Context>
Chris@16 88 static type call(boost::optional<Attribute> const& attr, Context& ctx)
Chris@16 89 {
Chris@16 90 return extract_from<Exposed>(boost::get<Attribute>(attr), ctx);
Chris@16 91 }
Chris@16 92 };
Chris@16 93
Chris@16 94 template <typename Attribute, typename Exposed>
Chris@16 95 struct extract_from_attribute<boost::optional<Attribute const>, Exposed>
Chris@16 96 {
Chris@16 97 typedef Attribute const& type;
Chris@16 98
Chris@16 99 template <typename Context>
Chris@16 100 static type call(boost::optional<Attribute const> const& attr, Context& ctx)
Chris@16 101 {
Chris@16 102 return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx);
Chris@16 103 }
Chris@16 104 };
Chris@16 105
Chris@16 106 // This handles attributes wrapped inside a boost::ref().
Chris@16 107 template <typename Attribute, typename Exposed>
Chris@16 108 struct extract_from_attribute<reference_wrapper<Attribute>, Exposed>
Chris@16 109 {
Chris@16 110 typedef Attribute const& type;
Chris@16 111
Chris@16 112 template <typename Context>
Chris@16 113 static type call(reference_wrapper<Attribute> const& attr, Context& ctx)
Chris@16 114 {
Chris@16 115 return extract_from<Exposed>(attr.get(), ctx);
Chris@16 116 }
Chris@16 117 };
Chris@16 118
Chris@16 119 ///////////////////////////////////////////////////////////////////////////
Chris@16 120 template <typename Attribute, typename Exposed, typename Enable>
Chris@16 121 struct extract_from_container
Chris@16 122 {
Chris@16 123 typedef typename traits::container_value<Attribute const>::type
Chris@16 124 value_type;
Chris@16 125 typedef typename is_convertible<value_type, Exposed>::type
Chris@16 126 is_convertible_to_value_type;
Chris@16 127
Chris@16 128 typedef typename mpl::if_<
Chris@16 129 mpl::or_<
Chris@16 130 is_same<value_type, Exposed>, is_same<Attribute, Exposed> >
Chris@16 131 , Exposed const&, Exposed
Chris@16 132 >::type type;
Chris@16 133
Chris@16 134 // handle case where container value type is convertible to result type
Chris@16 135 // we simply return the front element of the container
Chris@16 136 template <typename Context, typename Pred>
Chris@16 137 static type call(Attribute const& attr, Context&, mpl::true_, Pred)
Chris@16 138 {
Chris@16 139 // return first element from container
Chris@16 140 typedef typename traits::container_iterator<Attribute const>::type
Chris@16 141 iterator_type;
Chris@16 142
Chris@16 143 iterator_type it = traits::begin(attr);
Chris@16 144 type result = *it;
Chris@16 145 ++it;
Chris@16 146 return result;
Chris@16 147 }
Chris@16 148
Chris@16 149 // handle strings
Chris@16 150 template <typename Iterator>
Chris@16 151 static void append_to_string(Exposed& result, Iterator begin, Iterator end)
Chris@16 152 {
Chris@16 153 for (Iterator i = begin; i != end; ++i)
Chris@16 154 push_back(result, *i);
Chris@16 155 }
Chris@16 156
Chris@16 157 template <typename Context>
Chris@16 158 static type call(Attribute const& attr, Context&, mpl::false_, mpl::true_)
Chris@16 159 {
Chris@16 160 typedef typename char_type_of<Attribute>::type char_type;
Chris@16 161
Chris@16 162 Exposed result;
Chris@16 163 append_to_string(result, traits::get_begin<char_type>(attr)
Chris@16 164 , traits::get_end<char_type>(attr));
Chris@16 165 return result;
Chris@16 166 }
Chris@16 167
Chris@16 168 // everything else gets just passed through
Chris@16 169 template <typename Context>
Chris@16 170 static type call(Attribute const& attr, Context&, mpl::false_, mpl::false_)
Chris@16 171 {
Chris@16 172 return type(attr);
Chris@16 173 }
Chris@16 174
Chris@16 175 template <typename Context>
Chris@16 176 static type call(Attribute const& attr, Context& ctx)
Chris@16 177 {
Chris@16 178 typedef typename mpl::and_<
Chris@16 179 traits::is_string<Exposed>, traits::is_string<Attribute>
Chris@16 180 >::type handle_strings;
Chris@16 181
Chris@16 182 // return first element from container
Chris@16 183 return call(attr, ctx, is_convertible_to_value_type()
Chris@16 184 , handle_strings());
Chris@16 185 }
Chris@16 186 };
Chris@16 187
Chris@16 188 template <typename Attribute>
Chris@16 189 struct extract_from_container<Attribute, Attribute>
Chris@16 190 {
Chris@16 191 typedef Attribute const& type;
Chris@16 192
Chris@16 193 template <typename Context>
Chris@16 194 static type call(Attribute const& attr, Context&)
Chris@16 195 {
Chris@16 196 return attr;
Chris@16 197 }
Chris@16 198 };
Chris@16 199
Chris@16 200 ///////////////////////////////////////////////////////////////////////////
Chris@16 201 namespace detail
Chris@16 202 {
Chris@16 203 // overload for non-container attributes
Chris@16 204 template <typename Exposed, typename Attribute, typename Context>
Chris@16 205 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
Chris@16 206 extract_from(Attribute const& attr, Context& ctx, mpl::false_)
Chris@16 207 {
Chris@16 208 return extract_from_attribute<Attribute, Exposed>::call(attr, ctx);
Chris@16 209 }
Chris@16 210
Chris@16 211 // overload for containers (but not for variants or optionals
Chris@16 212 // holding containers)
Chris@16 213 template <typename Exposed, typename Attribute, typename Context>
Chris@16 214 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
Chris@16 215 extract_from(Attribute const& attr, Context& ctx, mpl::true_)
Chris@16 216 {
Chris@16 217 return extract_from_container<Attribute, Exposed>::call(attr, ctx);
Chris@16 218 }
Chris@16 219 }
Chris@16 220
Chris@16 221 template <typename Exposed, typename Attribute, typename Context>
Chris@16 222 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
Chris@16 223 extract_from(Attribute const& attr, Context& ctx
Chris@16 224 #if (defined(__GNUC__) && (__GNUC__ < 4)) || \
Chris@16 225 (defined(__APPLE__) && defined(__INTEL_COMPILER))
Chris@16 226 , typename enable_if<traits::not_is_unused<Attribute> >::type*
Chris@16 227 #endif
Chris@16 228 )
Chris@16 229 {
Chris@16 230 typedef typename mpl::and_<
Chris@16 231 traits::is_container<Attribute>
Chris@16 232 , traits::not_is_variant<Attribute>
Chris@16 233 , traits::not_is_optional<Attribute>
Chris@16 234 >::type is_not_wrapped_container;
Chris@16 235
Chris@16 236 return detail::extract_from<Exposed>(attr, ctx
Chris@16 237 , is_not_wrapped_container());
Chris@16 238 }
Chris@16 239
Chris@16 240 template <typename Exposed, typename Context>
Chris@16 241 inline unused_type extract_from(unused_type, Context&)
Chris@16 242 {
Chris@16 243 return unused;
Chris@16 244 }
Chris@16 245 }}}
Chris@16 246
Chris@16 247 ///////////////////////////////////////////////////////////////////////////////
Chris@16 248 namespace boost { namespace spirit { namespace result_of
Chris@16 249 {
Chris@16 250 template <typename Exposed, typename Attribute>
Chris@16 251 struct extract_from
Chris@16 252 : mpl::if_<
Chris@16 253 mpl::and_<
Chris@16 254 traits::is_container<Attribute>
Chris@16 255 , traits::not_is_variant<Attribute>
Chris@16 256 , traits::not_is_optional<Attribute> >
Chris@16 257 , traits::extract_from_container<Attribute, Exposed>
Chris@16 258 , traits::extract_from_attribute<Attribute, Exposed> >::type
Chris@16 259 {};
Chris@16 260
Chris@16 261 template <typename Exposed>
Chris@16 262 struct extract_from<Exposed, unused_type>
Chris@16 263 {
Chris@16 264 typedef unused_type type;
Chris@16 265 };
Chris@16 266
Chris@16 267 template <typename Exposed>
Chris@16 268 struct extract_from<Exposed, unused_type const>
Chris@16 269 {
Chris@16 270 typedef unused_type type;
Chris@16 271 };
Chris@16 272 }}}
Chris@16 273
Chris@16 274 #endif