Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/spirit/home/karma/detail/extract_from.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/spirit/home/karma/detail/extract_from.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,274 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM) +#define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/home/support/unused.hpp> +#include <boost/spirit/home/support/attributes_fwd.hpp> +#include <boost/spirit/home/karma/detail/attributes.hpp> +#include <boost/spirit/home/support/container.hpp> + +#include <boost/ref.hpp> +#include <boost/optional.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + // This file contains attribute extraction utilities. The utilities + // provided also accept spirit's unused_type; all no-ops. Compiler + // optimization will easily strip these away. + /////////////////////////////////////////////////////////////////////////// + + namespace detail + { + /////////////////////////////////////////////////////////////////////// + // extract first and second element of a fusion sequence + template <typename T> + struct add_const_ref + : add_reference<typename add_const<T>::type> + {}; + + template <typename T, int N> + struct value_at_c + : add_const_ref<typename fusion::result_of::value_at_c<T, N>::type> + {}; + } + + // This is the default case: the plain attribute values + template <typename Attribute, typename Exposed, typename Enable/*= void*/> + struct extract_from_attribute + { + typedef typename traits::one_element_sequence<Attribute>::type + is_one_element_sequence; + + typedef typename mpl::eval_if< + is_one_element_sequence + , detail::value_at_c<Attribute, 0> + , mpl::identity<Attribute const&> + >::type type; + + template <typename Context> + static type call(Attribute const& attr, Context&, mpl::false_) + { + return attr; + } + + // This handles the case where the attribute is a single element fusion + // sequence. We silently extract the only element and treat it as the + // attribute to generate output from. + template <typename Context> + static type call(Attribute const& attr, Context& ctx, mpl::true_) + { + return extract_from<Exposed>(fusion::at_c<0>(attr), ctx); + } + + template <typename Context> + static type call(Attribute const& attr, Context& ctx) + { + return call(attr, ctx, is_one_element_sequence()); + } + }; + + // This handles optional attributes. + template <typename Attribute, typename Exposed> + struct extract_from_attribute<boost::optional<Attribute>, Exposed> + { + typedef Attribute const& type; + + template <typename Context> + static type call(boost::optional<Attribute> const& attr, Context& ctx) + { + return extract_from<Exposed>(boost::get<Attribute>(attr), ctx); + } + }; + + template <typename Attribute, typename Exposed> + struct extract_from_attribute<boost::optional<Attribute const>, Exposed> + { + typedef Attribute const& type; + + template <typename Context> + static type call(boost::optional<Attribute const> const& attr, Context& ctx) + { + return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx); + } + }; + + // This handles attributes wrapped inside a boost::ref(). + template <typename Attribute, typename Exposed> + struct extract_from_attribute<reference_wrapper<Attribute>, Exposed> + { + typedef Attribute const& type; + + template <typename Context> + static type call(reference_wrapper<Attribute> const& attr, Context& ctx) + { + return extract_from<Exposed>(attr.get(), ctx); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename Attribute, typename Exposed, typename Enable> + struct extract_from_container + { + typedef typename traits::container_value<Attribute const>::type + value_type; + typedef typename is_convertible<value_type, Exposed>::type + is_convertible_to_value_type; + + typedef typename mpl::if_< + mpl::or_< + is_same<value_type, Exposed>, is_same<Attribute, Exposed> > + , Exposed const&, Exposed + >::type type; + + // handle case where container value type is convertible to result type + // we simply return the front element of the container + template <typename Context, typename Pred> + static type call(Attribute const& attr, Context&, mpl::true_, Pred) + { + // return first element from container + typedef typename traits::container_iterator<Attribute const>::type + iterator_type; + + iterator_type it = traits::begin(attr); + type result = *it; + ++it; + return result; + } + + // handle strings + template <typename Iterator> + static void append_to_string(Exposed& result, Iterator begin, Iterator end) + { + for (Iterator i = begin; i != end; ++i) + push_back(result, *i); + } + + template <typename Context> + static type call(Attribute const& attr, Context&, mpl::false_, mpl::true_) + { + typedef typename char_type_of<Attribute>::type char_type; + + Exposed result; + append_to_string(result, traits::get_begin<char_type>(attr) + , traits::get_end<char_type>(attr)); + return result; + } + + // everything else gets just passed through + template <typename Context> + static type call(Attribute const& attr, Context&, mpl::false_, mpl::false_) + { + return type(attr); + } + + template <typename Context> + static type call(Attribute const& attr, Context& ctx) + { + typedef typename mpl::and_< + traits::is_string<Exposed>, traits::is_string<Attribute> + >::type handle_strings; + + // return first element from container + return call(attr, ctx, is_convertible_to_value_type() + , handle_strings()); + } + }; + + template <typename Attribute> + struct extract_from_container<Attribute, Attribute> + { + typedef Attribute const& type; + + template <typename Context> + static type call(Attribute const& attr, Context&) + { + return attr; + } + }; + + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + // overload for non-container attributes + template <typename Exposed, typename Attribute, typename Context> + inline typename spirit::result_of::extract_from<Exposed, Attribute>::type + extract_from(Attribute const& attr, Context& ctx, mpl::false_) + { + return extract_from_attribute<Attribute, Exposed>::call(attr, ctx); + } + + // overload for containers (but not for variants or optionals + // holding containers) + template <typename Exposed, typename Attribute, typename Context> + inline typename spirit::result_of::extract_from<Exposed, Attribute>::type + extract_from(Attribute const& attr, Context& ctx, mpl::true_) + { + return extract_from_container<Attribute, Exposed>::call(attr, ctx); + } + } + + template <typename Exposed, typename Attribute, typename Context> + inline typename spirit::result_of::extract_from<Exposed, Attribute>::type + extract_from(Attribute const& attr, Context& ctx +#if (defined(__GNUC__) && (__GNUC__ < 4)) || \ + (defined(__APPLE__) && defined(__INTEL_COMPILER)) + , typename enable_if<traits::not_is_unused<Attribute> >::type* +#endif + ) + { + typedef typename mpl::and_< + traits::is_container<Attribute> + , traits::not_is_variant<Attribute> + , traits::not_is_optional<Attribute> + >::type is_not_wrapped_container; + + return detail::extract_from<Exposed>(attr, ctx + , is_not_wrapped_container()); + } + + template <typename Exposed, typename Context> + inline unused_type extract_from(unused_type, Context&) + { + return unused; + } +}}} + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace result_of +{ + template <typename Exposed, typename Attribute> + struct extract_from + : mpl::if_< + mpl::and_< + traits::is_container<Attribute> + , traits::not_is_variant<Attribute> + , traits::not_is_optional<Attribute> > + , traits::extract_from_container<Attribute, Exposed> + , traits::extract_from_attribute<Attribute, Exposed> >::type + {}; + + template <typename Exposed> + struct extract_from<Exposed, unused_type> + { + typedef unused_type type; + }; + + template <typename Exposed> + struct extract_from<Exposed, unused_type const> + { + typedef unused_type type; + }; +}}} + +#endif