summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/support
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/support')
-rw-r--r--boost/spirit/home/x3/support/ast/position_tagged.hpp96
-rw-r--r--boost/spirit/home/x3/support/ast/variant.hpp249
-rw-r--r--boost/spirit/home/x3/support/context.hpp135
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp512
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_int.hpp147
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_real.hpp271
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/pow10.hpp116
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/sign.hpp48
-rw-r--r--boost/spirit/home/x3/support/subcontext.hpp89
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_category.hpp82
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_of.hpp59
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_type.hpp30
-rw-r--r--boost/spirit/home/x3/support/traits/container_traits.hpp333
-rw-r--r--boost/spirit/home/x3/support/traits/handles_container.hpp31
-rw-r--r--boost/spirit/home/x3/support/traits/has_attribute.hpp63
-rw-r--r--boost/spirit/home/x3/support/traits/is_parser.hpp37
-rw-r--r--boost/spirit/home/x3/support/traits/is_substitute.hpp164
-rw-r--r--boost/spirit/home/x3/support/traits/is_variant.hpp45
-rw-r--r--boost/spirit/home/x3/support/traits/make_attribute.hpp86
-rw-r--r--boost/spirit/home/x3/support/traits/move_to.hpp211
-rw-r--r--boost/spirit/home/x3/support/traits/numeric_traits.hpp128
-rw-r--r--boost/spirit/home/x3/support/traits/optional_traits.hpp78
-rw-r--r--boost/spirit/home/x3/support/traits/print_attribute.hpp150
-rw-r--r--boost/spirit/home/x3/support/traits/print_token.hpp79
-rw-r--r--boost/spirit/home/x3/support/traits/string_traits.hpp291
-rw-r--r--boost/spirit/home/x3/support/traits/transform_attribute.hpp48
-rw-r--r--boost/spirit/home/x3/support/traits/tuple_traits.hpp52
-rw-r--r--boost/spirit/home/x3/support/traits/value_traits.hpp30
-rw-r--r--boost/spirit/home/x3/support/traits/variant_find_substitute.hpp56
-rw-r--r--boost/spirit/home/x3/support/traits/variant_has_substitute.hpp56
-rw-r--r--boost/spirit/home/x3/support/unused.hpp93
-rw-r--r--boost/spirit/home/x3/support/utility/detail/testing.hpp16
-rw-r--r--boost/spirit/home/x3/support/utility/error_reporting.hpp241
-rw-r--r--boost/spirit/home/x3/support/utility/integer_sequence.hpp94
-rw-r--r--boost/spirit/home/x3/support/utility/is_callable.hpp45
-rw-r--r--boost/spirit/home/x3/support/utility/lambda_visitor.hpp49
-rw-r--r--boost/spirit/home/x3/support/utility/sfinae.hpp29
-rw-r--r--boost/spirit/home/x3/support/utility/testing.hpp69
-rw-r--r--boost/spirit/home/x3/support/utility/unrefcv.hpp29
-rw-r--r--boost/spirit/home/x3/support/utility/utf8.hpp72
40 files changed, 4509 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/support/ast/position_tagged.hpp b/boost/spirit/home/x3/support/ast/position_tagged.hpp
new file mode 100644
index 0000000000..22cfd7588b
--- /dev/null
+++ b/boost/spirit/home/x3/support/ast/position_tagged.hpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 2014 Joel de Guzman
+
+ 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_X3_POSITION_TAGGED_MAY_01_2014_0321PM)
+#define BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct position_tagged
+ {
+ // Use this to annotate an AST with the iterator position.
+ // These ids are used as a key to the position_cache (below)
+ // and marks the start and end of an AST node.
+ int id_first = -1;
+ int id_last = -1;
+ };
+
+ template <typename Container>
+ class position_cache
+ {
+ public:
+
+ typedef typename Container::value_type iterator_type;
+
+ position_cache(
+ iterator_type first
+ , iterator_type last)
+ : first_(first), last_(last) {}
+
+ // This will catch all nodes inheriting from position_tagged
+ boost::iterator_range<iterator_type>
+ position_of(position_tagged const& ast) const
+ {
+ return
+ boost::iterator_range<iterator_type>(
+ positions.at(ast.id_first) // throws if out of range
+ , positions.at(ast.id_last) // throws if out of range
+ );
+ }
+
+ // This will catch all nodes except those inheriting from position_tagged
+ template <typename AST>
+ boost::iterator_range<iterator_type>
+ position_of(AST const& ast) const
+ {
+ // returns an empty position
+ return boost::iterator_range<iterator_type>();
+ }
+
+ // This will catch all nodes except those inheriting from position_tagged
+ template <typename AST>
+ void annotate(AST& ast, iterator_type first, iterator_type last, mpl::false_)
+ {
+ // (no-op) no need for tags
+ }
+
+ // This will catch all nodes inheriting from position_tagged
+ void annotate(position_tagged& ast, iterator_type first, iterator_type last, mpl::true_)
+ {
+ ast.id_first = int(positions.size());
+ positions.push_back(first);
+ ast.id_last = int(positions.size());
+ positions.push_back(last);
+ }
+
+ template <typename AST>
+ void annotate(AST& ast, iterator_type first, iterator_type last)
+ {
+ annotate(ast, first, last, is_base_of<position_tagged, AST>());
+ }
+
+ Container const&
+ get_positions() const
+ {
+ return positions;
+ }
+
+ iterator_type first() const { return first_; }
+ iterator_type last() const { return last_; }
+
+ private:
+
+ Container positions;
+ iterator_type first_;
+ iterator_type last_;
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/ast/variant.hpp b/boost/spirit/home/x3/support/ast/variant.hpp
new file mode 100644
index 0000000000..cf626e88be
--- /dev/null
+++ b/boost/spirit/home/x3/support/ast/variant.hpp
@@ -0,0 +1,249 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ 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_X3_VARIANT_AUGUST_6_2011_0859AM)
+#define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T>
+ class forward_ast
+ {
+ public:
+
+ typedef T type;
+
+ public:
+
+ forward_ast() : p_(new T) {}
+
+ forward_ast(forward_ast const& operand)
+ : p_(new T(operand.get())) {}
+
+ forward_ast(forward_ast&& operand)
+ : p_(operand.p_)
+ {
+ operand.p_ = 0;
+ }
+
+ forward_ast(T const& operand)
+ : p_(new T(operand)) {}
+
+ forward_ast(T&& operand)
+ : p_(new T(std::move(operand))) {}
+
+ ~forward_ast()
+ {
+ boost::checked_delete(p_);
+ }
+
+ forward_ast& operator=(forward_ast const& rhs)
+ {
+ assign(rhs.get());
+ return *this;
+ }
+
+ void swap(forward_ast& operand) BOOST_NOEXCEPT
+ {
+ T* temp = operand.p_;
+ operand.p_ = p_;
+ p_ = temp;
+ }
+
+ forward_ast& operator=(T const& rhs)
+ {
+ assign(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
+ {
+ swap(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(T&& rhs)
+ {
+ get() = std::move(rhs);
+ return *this;
+ }
+
+ T& get() { return *get_pointer(); }
+ const T& get() const { return *get_pointer(); }
+
+ T* get_pointer() { return p_; }
+ const T* get_pointer() const { return p_; }
+
+ operator T const&() const { return this->get(); }
+ operator T&() { return this->get(); }
+
+ private:
+
+ void assign(const T& rhs)
+ {
+ this->get() = rhs;
+ }
+
+ T* p_;
+ };
+
+ // function template swap
+ //
+ // Swaps two forward_ast<T> objects of the same type T.
+ //
+ template <typename T>
+ inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+ namespace detail
+ {
+ template <typename T>
+ struct remove_forward : mpl::identity<T>
+ {};
+
+ template <typename T>
+ struct remove_forward<forward_ast<T>> : mpl::identity<T>
+ {};
+ }
+
+ template <typename ...Types>
+ struct variant
+ {
+ // tell spirit that this is an adapted variant
+ struct adapted_variant_tag;
+
+ typedef boost::variant<Types...> variant_type;
+ typedef mpl::list<typename detail::remove_forward<Types>::type...> types;
+ typedef variant<Types...> base_type;
+
+ variant() : var() {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T const& rhs)
+ : var(rhs) {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T&& rhs)
+ : var(std::forward<T>(rhs)) {}
+
+ variant(variant const& rhs)
+ : var(rhs.var) {}
+
+ variant(variant& rhs)
+ : var(rhs.var) {}
+
+ variant(variant&& rhs)
+ : var(std::forward<variant_type>(rhs.var)) {}
+
+ variant& operator=(variant const& rhs)
+ {
+ var = rhs.get();
+ return *this;
+ }
+
+ variant& operator=(variant&& rhs)
+ {
+ var = std::forward<variant_type>(rhs.get());
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T const& rhs)
+ {
+ var = rhs;
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T&& rhs)
+ {
+ var = std::forward<T>(rhs);
+ return *this;
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F const& v)
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F const& v) const
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F& v)
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F& v) const
+ {
+ return var.apply_visitor(v);
+ }
+
+ variant_type const& get() const
+ {
+ return var;
+ }
+
+ variant_type& get()
+ {
+ return var;
+ }
+
+ variant_type var;
+ };
+}}}
+
+namespace boost
+{
+ template <typename T, typename ...Types>
+ inline T const&
+ get(boost::spirit::x3::variant<Types...> const& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T&
+ get(boost::spirit::x3::variant<Types...>& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T const*
+ get(boost::spirit::x3::variant<Types...> const* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T*
+ get(boost::spirit::x3::variant<Types...>* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+}
+
+#endif
diff --git a/boost/spirit/home/x3/support/context.hpp b/boost/spirit/home/x3/support/context.hpp
new file mode 100644
index 0000000000..93bcb24070
--- /dev/null
+++ b/boost/spirit/home/x3/support/context.hpp
@@ -0,0 +1,135 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_CONTEXT_JAN_4_2012_1215PM)
+#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename ID, typename T, typename Next = unused_type>
+ struct context
+ {
+ context(T& val, Next const& next)
+ : val(val), next(next) {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef typename Next::template get_result<ID_>::type type;
+ };
+
+ template <typename Unused>
+ struct get_result<mpl::identity<ID>, Unused>
+ {
+ typedef T& type;
+ };
+
+ T& get(mpl::identity<ID>) const
+ {
+ return val;
+ }
+
+ template <typename ID_>
+ typename Next::template get_result<ID_>::type
+ get(ID_ id) const
+ {
+ return next.get(id);
+ }
+
+ T& val;
+ Next const& next;
+ };
+
+ template <typename ID, typename T>
+ struct context<ID, T, unused_type>
+ {
+ context(T& val)
+ : val(val) {}
+
+ context(T& val, unused_type)
+ : val(val) {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef unused_type type;
+ };
+
+ template <typename Unused>
+ struct get_result<mpl::identity<ID>, Unused>
+ {
+ typedef T& type;
+ };
+
+ T& get(mpl::identity<ID>) const
+ {
+ return val;
+ }
+
+ template <typename ID_>
+ unused_type
+ get(ID_) const
+ {
+ return unused;
+ }
+
+ T& val;
+ };
+
+ template <typename Tag, typename Context>
+ inline auto
+ get(Context const& context)
+ -> decltype(context.get(mpl::identity<Tag>()))
+ {
+ return context.get(mpl::identity<Tag>());
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline context<ID, T, Next> make_context(T& val, Next const& next)
+ {
+ return context<ID, T, Next>(val, next);
+ }
+
+ template <typename ID, typename T>
+ inline context<ID, T> make_context(T& val)
+ {
+ return context<ID, T>(val);
+ }
+
+ namespace detail
+ {
+ template <typename ID, typename T, typename Next, typename FoundVal>
+ inline Next const&
+ make_unique_context(T& val, Next const& next, FoundVal&)
+ {
+ return next;
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline context<ID, T, Next>
+ make_unique_context(T& val, Next const& next, unused_type)
+ {
+ return context<ID, T, Next>(val, next);
+ }
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline auto
+ make_unique_context(T& val, Next const& next)
+ {
+ return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
new file mode 100644
index 0000000000..73770c87d0
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
@@ -0,0 +1,512 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Jan Frederick Eick
+ Copyright (c) 2011 Christopher Jefferson
+ Copyright (c) 2006 Stephen Nutt
+
+ 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_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
+#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/comparison/less.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+
+#include <boost/detail/iterator.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/limits.hpp>
+
+#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
+# define SPIRIT_NUMERICS_LOOP_UNROLL 3
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The maximum radix digits that can be represented without
+ // overflow:
+ //
+ // template<typename T, unsigned Radix>
+ // struct digits_traits::value;
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix>
+ struct digits_traits;
+
+// lookup table for log2(x) : 2 <= x <= 36
+#define BOOST_SPIRIT_X3_LOG2 (#error)(#error) \
+ (1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
+ (3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
+ (3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
+ (4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
+ (4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
+ (5000000)(5044390)(5087460)(5129280)(5169925) \
+ /***/
+
+#define BOOST_PP_LOCAL_MACRO(Radix) \
+ template <typename T> struct digits_traits<T, Radix> \
+ { \
+ typedef std::numeric_limits<T> numeric_limits_type; \
+ BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
+ (numeric_limits_type::digits * 1000000) / \
+ BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2))); \
+ }; \
+ /***/
+
+#define BOOST_PP_LOCAL_LIMITS (2, 36)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#undef BOOST_SPIRIT_X3_LOG2
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Traits class for radix specific number conversion
+ //
+ // Test the validity of a single character:
+ //
+ // template<typename Char> static bool is_valid(Char ch);
+ //
+ // Convert a digit from character representation to binary
+ // representation:
+ //
+ // template<typename Char> static int digit(Char ch);
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct radix_traits
+ {
+ template <typename Char>
+ inline static bool is_valid(Char ch)
+ {
+ if (Radix <= 10)
+ return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
+ return (ch >= '0' && ch <= '9')
+ || (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
+ || (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
+ }
+
+ template <typename Char>
+ inline static unsigned digit(Char ch)
+ {
+ if (Radix <= 10 || (ch >= '0' && ch <= '9'))
+ return ch - '0';
+ return char_encoding::ascii::tolower(ch) - 'a' + 10;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // positive_accumulator/negative_accumulator: Accumulator policies for
+ // extracting integers. Use positive_accumulator if number is positive.
+ // Use negative_accumulator if number is negative.
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct positive_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked add
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) + T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked add
+ {
+ // Ensure n *= Radix will not overflow
+ static T const max = (std::numeric_limits<T>::max)();
+ static T const val = max / Radix;
+ if (n > val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n += digit will not overflow
+ const int digit = radix_traits<Radix>::digit(ch);
+ if (n > max - digit)
+ return false;
+
+ n += static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ template <unsigned Radix>
+ struct negative_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) - T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
+ {
+ // Ensure n *= Radix will not underflow
+ static T const min = (std::numeric_limits<T>::min)();
+ static T const val = (min + 1) / T(Radix);
+ if (n < val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n -= digit will not underflow
+ int const digit = radix_traits<Radix>::digit(ch);
+ if (n < min + digit)
+ return false;
+
+ n -= static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Common code for extract_int::parse specializations
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix, typename Accumulator, int MaxDigits>
+ struct int_extractor
+ {
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n, mpl::true_)
+ {
+ static std::size_t const
+ overflow_free = digits_traits<T, Radix>::value - 1;
+
+ if (count < overflow_free)
+ {
+ Accumulator::add(n, ch, mpl::false_());
+ }
+ else
+ {
+ if (!Accumulator::add(n, ch, mpl::true_()))
+ return false; // over/underflow!
+ }
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
+ {
+ // no need to check for overflow
+ Accumulator::add(n, ch, mpl::false_());
+ return true;
+ }
+
+ template <typename Char>
+ inline static bool
+ call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
+ {
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n)
+ {
+ return call(ch, count, n
+ , mpl::bool_<
+ ( (MaxDigits < 0)
+ || (MaxDigits > digits_traits<T, Radix>::value)
+ )
+ && traits::check_overflow<T>::value
+ >()
+ );
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // End of loop checking: check if the number of digits
+ // being parsed exceeds MaxDigits. Note: if MaxDigits == -1
+ // we don't do any checking.
+ ///////////////////////////////////////////////////////////////////////////
+ template <int MaxDigits>
+ struct check_max_digits
+ {
+ inline static bool
+ call(std::size_t count)
+ {
+ return count < MaxDigits; // bounded
+ }
+ };
+
+ template <>
+ struct check_max_digits<-1>
+ {
+ inline static bool
+ call(std::size_t /*count*/)
+ {
+ return true; // unbounded
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
+ || it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
+ break; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <
+ typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , typename Accumulator = positive_accumulator<Radix>
+ , bool Accumulate = false
+ >
+ struct extract_int
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t leading_zeros = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0' && leading_zeros < MaxDigits)
+ {
+ ++it;
+ ++leading_zeros;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ std::size_t count = 0;
+ char_type ch;
+
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ if (count + leading_zeros >= MinDigits)
+ {
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+ return false;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ // common case where MinDigits == 1 and MaxDigits = -1
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch)) \
+ break; \
+ if (!extractor::call(ch, count, val)) \
+ return false; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
+ struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, -1> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t count = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0')
+ {
+ ++it;
+ ++count;
+ }
+
+ if (it == last)
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ attr = 0;
+ first = it;
+ return true;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ char_type ch = *it;
+
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+
+ count = 0;
+ ++it;
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Cast an signed integer to an unsigned integer
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T,
+ bool force_unsigned
+ = mpl::and_<is_integral<T>, is_signed<T> >::value>
+ struct cast_unsigned;
+
+ template <typename T>
+ struct cast_unsigned<T, true>
+ {
+ typedef typename make_unsigned<T>::type unsigned_type;
+ typedef typename make_unsigned<T>::type& unsigned_type_ref;
+
+ inline static unsigned_type_ref call(T& n)
+ {
+ return unsigned_type_ref(n);
+ }
+ };
+
+ template <typename T>
+ struct cast_unsigned<T, false>
+ {
+ inline static T& call(T& n)
+ {
+ return n;
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
new file mode 100644
index 0000000000..aa80cdd6ea
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2011 Jan Frederick Eick
+
+ 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_X3_EXTRACT_INT_APRIL_17_2006_0830AM)
+#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Extract the prefix sign (- or +), return true if a '-' was found
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ inline bool
+ extract_sign(Iterator& first, Iterator const& last)
+ {
+ (void)last; // silence unused warnings
+ BOOST_ASSERT(first != last); // precondition
+
+ // Extract the sign
+ bool neg = *first == '-';
+ if (neg || (*first == '+'))
+ {
+ ++first;
+ return neg;
+ }
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level unsigned integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , bool Accumulate = false>
+ struct extract_uint
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix >= 2 && Radix <= 36),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T
+ , Radix
+ , MinDigits
+ , MaxDigits
+ , detail::positive_accumulator<Radix>
+ , Accumulate>
+ extract_type;
+
+ Iterator save = first;
+ if (!extract_type::parse(first, last,
+ detail::cast_unsigned<T>::call(attr)))
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level signed integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+ struct extract_int
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits>
+ extract_pos_type;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
+ extract_neg_type;
+
+ Iterator save = first;
+ bool hit = extract_sign(first, last);
+ if (hit)
+ hit = extract_neg_type::parse(first, last, attr);
+ else
+ hit = extract_pos_type::parse(first, last, attr);
+
+ if (!hit)
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
new file mode 100644
index 0000000000..fb30f02306
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
@@ -0,0 +1,271 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM)
+#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <cmath>
+#include <boost/limits.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/pow10.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/sign.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/assert.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace extension
+{
+ using x3::traits::pow10;
+
+ template <typename T>
+ inline void
+ scale(int exp, T& n)
+ {
+ if (exp >= 0)
+ {
+ // $$$ Why is this failing for boost.math.concepts ? $$$
+ //~ int nn = std::numeric_limits<T>::max_exponent10;
+ //~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
+ n *= pow10<T>(exp);
+ }
+ else
+ {
+ if (exp < std::numeric_limits<T>::min_exponent10)
+ {
+ n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
+ n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
+ }
+ else
+ {
+ n /= pow10<T>(-exp);
+ }
+ }
+ }
+
+ inline void
+ scale(int /*exp*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ template <typename T>
+ inline void
+ scale(int exp, int frac, T& n)
+ {
+ scale(exp - frac, n);
+ }
+
+ inline void
+ scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ inline float
+ negate(bool neg, float n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline double
+ negate(bool neg, double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline long double
+ negate(bool neg, long double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ template <typename T>
+ inline T
+ negate(bool neg, T const& n)
+ {
+ return neg ? -n : n;
+ }
+
+ inline unused_type
+ negate(bool /*neg*/, unused_type n)
+ {
+ // no-op for unused_type
+ return n;
+ }
+
+ template <typename T>
+ inline bool
+ is_equal_to_one(T const& value)
+ {
+ return value == 1.0;
+ }
+
+ inline bool
+ is_equal_to_one(unused_type)
+ {
+ // no-op for unused_type
+ return false;
+ }
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, typename RealPolicies>
+ struct extract_real
+ {
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse(Iterator& first, Iterator const& last, Attribute& attr,
+ RealPolicies const& p)
+ {
+ if (first == last)
+ return false;
+ Iterator save = first;
+
+ // Start by parsing the sign. neg will be true if
+ // we got a "-" sign, false otherwise.
+ bool neg = p.parse_sign(first, last);
+
+ // Now attempt to parse an integer
+ T n = 0;
+ bool got_a_number = p.parse_n(first, last, n);
+
+ // If we did not get a number it might be a NaN, Inf or a leading
+ // dot.
+ if (!got_a_number)
+ {
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return early
+ }
+
+ // If we did not get a number and our policies do not
+ // allow a leading dot, fail and return early (no-match)
+ if (!p.allow_leading_dot)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ bool e_hit = false;
+ int frac_digits = 0;
+
+ // Try to parse the dot ('.' decimal point)
+ if (p.parse_dot(first, last))
+ {
+ // We got the decimal point. Now we will try to parse
+ // the fraction if it is there. If not, it defaults
+ // to zero (0) only if we already got a number.
+ Iterator savef = first;
+ if (p.parse_frac_n(first, last, n))
+ {
+ // Optimization note: don't compute frac_digits if T is
+ // an unused_type. This should be optimized away by the compiler.
+ if (!is_same<T, unused_type>::value)
+ frac_digits =
+ static_cast<int>(std::distance(savef, first));
+ }
+ else if (!got_a_number || !p.allow_trailing_dot)
+ {
+ // We did not get a fraction. If we still haven't got a
+ // number and our policies do not allow a trailing dot,
+ // return no-match.
+ first = save;
+ return false;
+ }
+
+ // Now, let's see if we can parse the exponent prefix
+ e_hit = p.parse_exp(first, last);
+ }
+ else
+ {
+ // No dot and no number! Return no-match.
+ if (!got_a_number)
+ {
+ first = save;
+ return false;
+ }
+
+ // If we must expect a dot and we didn't see an exponent
+ // prefix, return no-match.
+ e_hit = p.parse_exp(first, last);
+ if (p.expect_dot && !e_hit)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ if (e_hit)
+ {
+ // We got the exponent prefix. Now we will try to parse the
+ // actual exponent. It is an error if it is not there.
+ int exp = 0;
+ if (p.parse_exp_n(first, last, exp))
+ {
+ // Got the exponent value. Scale the number by
+ // exp-frac_digits.
+ extension::scale(exp, frac_digits, n);
+ }
+ else
+ {
+ // Oops, no exponent, return no-match.
+ first = save;
+ return false;
+ }
+ }
+ else if (frac_digits)
+ {
+ // No exponent found. Scale the number by -frac_digits.
+ extension::scale(-frac_digits, n);
+ }
+ else if (extension::is_equal_to_one(n))
+ {
+ // There is a chance of having to parse one of the 1.0#...
+ // styles some implementations use for representing NaN or Inf.
+
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return immediately
+ }
+ }
+
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+
+ // Success!!!
+ return true;
+ }
+ };
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/pow10.hpp b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
new file mode 100644
index 0000000000..f51d29fba8
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_POW10_DECEMBER_26_2008_1118AM)
+#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/limits.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ namespace detail
+ {
+ template <typename T, typename Enable = void>
+ struct pow10_helper
+ {
+ static T call(unsigned dim)
+ {
+ using namespace std; // allow for ADL to find the correct overload
+ return pow(T(10), T(dim));
+ }
+ };
+
+ template <>
+ struct pow10_helper<unused_type>
+ {
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+#if (DBL_MAX_10_EXP == 308) // for IEEE-754
+ template <>
+ struct pow10_helper<double>
+ {
+ static double call(unsigned dim)
+ {
+ static double const exponents[] =
+ {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
+ 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
+ 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
+ 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
+ 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
+ 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
+ 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
+ 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
+ };
+ BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
+ return exponents[dim];
+ }
+ };
+
+ template <>
+ struct pow10_helper<float>
+ {
+ static float call(unsigned dim)
+ {
+ return pow10_helper<double>::call(dim);
+ }
+ };
+#endif // for IEEE-754
+ }
+
+ template <typename T>
+ inline T pow10(unsigned dim)
+ {
+ return detail::pow10_helper<T>::call(dim);
+ }
+}}}}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/sign.hpp b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
new file mode 100644
index 0000000000..fe2feceeed
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(SPIRIT_SIGN_MAR_11_2009_0734PM)
+#define SPIRIT_SIGN_MAR_11_2009_0734PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template<typename T>
+ inline bool (signbit)(T x)
+ {
+ return (boost::math::signbit)(x) ? true : false;
+ }
+
+ // This routine has been taken and adapted from Johan Rade's fp_traits
+ // library
+ template<typename T>
+ inline T (changesign)(T x)
+ {
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
+ return -x;
+#else
+ typedef typename math::detail::fp_traits<T>::type traits_type;
+
+ typename traits_type::bits a;
+ traits_type::get_bits(x, a);
+ a ^= traits_type::sign;
+ traits_type::set_bits(x, a);
+ return x;
+#endif
+ }
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/subcontext.hpp b/boost/spirit/home/x3/support/subcontext.hpp
new file mode 100644
index 0000000000..7614fcbcae
--- /dev/null
+++ b/boost/spirit/home/x3/support/subcontext.hpp
@@ -0,0 +1,89 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustín Bergé
+ http://spirit.sourceforge.net/
+
+ 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_X3_SUBCONTEXT_APR_15_2013_0840AM)
+#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/support/pair.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename... T>
+ struct subcontext;
+
+ template <>
+ struct subcontext<>
+ {
+ template <typename Context>
+ subcontext(Context const& /*context*/)
+ {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef unused_type type;
+ };
+
+ template <typename ID_>
+ unused_type
+ get(ID_) const
+ {
+ return unused;
+ }
+ };
+
+ template <typename T>
+ struct subcontext<T>
+ : context<typename T::first_type, typename T::second_type>
+ {
+ typedef context<
+ typename T::first_type, typename T::second_type
+ > context_type;
+
+ template <typename Context>
+ subcontext(Context const& context)
+ : context_type(x3::get<typename T::first_type>(context))
+ {}
+
+ using context_type::get;
+ };
+
+ template <typename T, typename... Tail>
+ struct subcontext<T, Tail...>
+ : subcontext<Tail...>
+ , context<
+ typename T::first_type, typename T::second_type
+ , subcontext<Tail...>
+ >
+ {
+ typedef subcontext<Tail...> base_type;
+ typedef context<
+ typename T::first_type, typename T::second_type
+ , base_type
+ > context_type;
+
+ template <typename Context>
+ subcontext(Context const& context)
+ : base_type(context)
+ , context_type(
+ x3::get<typename T::first_type>(context)
+ , *static_cast<base_type*>(this))
+ {}
+
+ using context_type::get;
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_category.hpp b/boost/spirit/home/x3/support/traits/attribute_category.hpp
new file mode 100644
index 0000000000..a003327de2
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_category.hpp
@@ -0,0 +1,82 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/fusion/include/copy.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ struct unused_attribute {};
+ struct plain_attribute {};
+ struct container_attribute {};
+ struct tuple_attribute {};
+ struct associative_attribute {};
+ struct variant_attribute {};
+ struct optional_attribute {};
+
+ template <typename T, typename Enable = void>
+ struct attribute_category
+ : mpl::identity<plain_attribute> {};
+
+ template <>
+ struct attribute_category<unused_type>
+ : mpl::identity<unused_attribute> {};
+
+ template <>
+ struct attribute_category<unused_type const>
+ : mpl::identity<unused_attribute> {};
+
+ template <typename T>
+ struct attribute_category< T
+ , typename enable_if<
+ typename mpl::eval_if<
+ fusion::traits::is_sequence<T>
+ , fusion::traits::is_associative<T>
+ , mpl::false_
+ >::type >::type >
+ : mpl::identity<associative_attribute> {};
+
+ template <typename T>
+ struct attribute_category< T
+ , typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>
+ , mpl::not_<fusion::traits::is_associative<T> >
+ > >::type >
+ : mpl::identity<tuple_attribute> {};
+
+ template <typename T>
+ struct attribute_category<T,
+ typename enable_if<traits::is_variant<T>>::type>
+ : mpl::identity<variant_attribute> {};
+
+ template <typename T>
+ struct attribute_category<T,
+ typename enable_if<traits::is_container<T>>::type>
+ : mpl::identity<container_attribute> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_of.hpp b/boost/spirit/home/x3/support/traits/attribute_of.hpp
new file mode 100644
index 0000000000..71f70b0273
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_of.hpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the attribute type of a component. By default, this gets the
+ // Component's attribute_type typedef or instantiates a nested attribute
+ // metafunction. Components may specialize this if such an attribute_type
+ // is not readily available (e.g. expensive to compute at compile time).
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct attribute_of;
+
+ namespace detail
+ {
+ template <typename Component, typename Context, typename Enable = void>
+ struct default_attribute_of;
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename disable_if_substitution_failure<
+ typename Component::attribute_type>::type>
+ : mpl::identity<typename Component::attribute_type> {};
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename disable_if_substitution_failure<
+ typename Component::template attribute<Context>::type>::type>
+ : Component::template attribute<Context> {};
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename enable_if_c<Component::is_pass_through_unary>::type>
+ : attribute_of<typename Component::subject_type, Context>{};
+ }
+
+ template <typename Component, typename Context, typename Enable>
+ struct attribute_of : detail::default_attribute_of<Component, Context> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_type.hpp b/boost/spirit/home/x3/support/traits/attribute_type.hpp
new file mode 100644
index 0000000000..55e788b41c
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_type.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Retrieve the attribute type to use from the given type
+ //
+ // This is needed to extract the correct attribute type from proxy classes
+ // as utilized in FUSION_ADAPT_ADT et. al.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Enable = void>
+ struct attribute_type : mpl::identity<Attribute> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/container_traits.hpp b/boost/spirit/home/x3/support/traits/container_traits.hpp
new file mode 100644
index 0000000000..c382b7bfaa
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/container_traits.hpp
@@ -0,0 +1,333 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
+#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/fusion/include/deque.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <vector>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // This file contains some container utils for stl containers.
+ ///////////////////////////////////////////////////////////////////////////
+
+ namespace detail
+ {
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
+ }
+
+ template <typename T, typename Enable = void>
+ struct is_container
+ : mpl::bool_<
+ detail::has_value_type<T>::value &&
+ detail::has_iterator<T>::value &&
+ detail::has_size_type<T>::value &&
+ detail::has_reference<T>::value>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ struct remove_value_const : mpl::identity<T> {};
+
+ template <typename T>
+ struct remove_value_const<T const> : remove_value_const<T> {};
+
+ template <typename F, typename S>
+ struct remove_value_const<std::pair<F, S>>
+ {
+ typedef typename remove_value_const<F>::type first_type;
+ typedef typename remove_value_const<S>::type second_type;
+ typedef std::pair<first_type, second_type> type;
+ };
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct container_value
+ : detail::remove_value_const<typename Container::value_type>
+ {};
+
+ template <typename Container>
+ struct container_value<Container const> : container_value<Container> {};
+
+ // There is no single container value for fusion maps, but because output
+ // of this metafunc is used to check wheter parser's attribute can be
+ // saved to container, we simply return whole fusion::map as is
+ // so that check can be done in traits::is_substitute specialisation
+ template <typename T>
+ struct container_value<T
+ , typename enable_if<typename mpl::eval_if <
+ fusion::traits::is_sequence<T>
+ , fusion::traits::is_associative<T>
+ , mpl::false_ >::type >::type>
+ : mpl::identity<T> {};
+
+ template <>
+ struct container_value<unused_type> : mpl::identity<unused_type> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct container_iterator
+ : mpl::identity<typename Container::iterator> {};
+
+ template <typename Container>
+ struct container_iterator<Container const>
+ : mpl::identity<typename Container::const_iterator> {};
+
+ template <>
+ struct container_iterator<unused_type>
+ : mpl::identity<unused_type const*> {};
+
+ template <>
+ struct container_iterator<unused_type const>
+ : mpl::identity<unused_type const*> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename T>
+ bool push_back(Container& c, T&& val);
+
+ template <typename Container, typename Enable = void>
+ struct push_back_container
+ {
+ template <typename T>
+ static bool call(Container& c, T&& val)
+ {
+ c.insert(c.end(), std::move(val));
+ return true;
+ }
+ };
+
+ template <typename Container, typename T>
+ inline bool push_back(Container& c, T&& val)
+ {
+ return push_back_container<Container>::call(c, std::move(val));
+ }
+
+ template <typename Container>
+ inline bool push_back(Container&, unused_type)
+ {
+ return true;
+ }
+
+ template <typename T>
+ inline bool push_back(unused_type, T const&)
+ {
+ return true;
+ }
+
+ inline bool push_back(unused_type, unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Iterator>
+ bool append(Container& c, Iterator first, Iterator last);
+
+ template <typename Container, typename Enable = void>
+ struct append_container
+ {
+ // Not all containers have "reserve"
+ template <typename Container_>
+ static void reserve(Container_& c, std::size_t size) {}
+
+ template <typename T>
+ static void reserve(std::vector<T>& c, std::size_t size)
+ {
+ c.reserve(size);
+ }
+
+ template <typename Iterator>
+ static bool call(Container& c, Iterator first, Iterator last)
+ {
+ reserve(c, c.size() + std::distance(first, last));
+ c.insert(c.end(), first, last);
+ return true;
+ }
+ };
+
+ template <typename Container, typename Iterator>
+ inline bool append(Container& c, Iterator first, Iterator last)
+ {
+ return append_container<Container>::call(c, first, last);
+ }
+
+ template <typename Iterator>
+ inline bool append(unused_type, Iterator first, Iterator last)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct is_empty_container
+ {
+ static bool call(Container const& c)
+ {
+ return c.empty();
+ }
+ };
+
+ template <typename Container>
+ inline bool is_empty(Container const& c)
+ {
+ return is_empty_container<Container>::call(c);
+ }
+
+ inline bool is_empty(unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct begin_container
+ {
+ static typename container_iterator<Container>::type call(Container& c)
+ {
+ return c.begin();
+ }
+ };
+
+ template <typename Container>
+ inline typename container_iterator<Container>::type
+ begin(Container& c)
+ {
+ return begin_container<Container>::call(c);
+ }
+
+ inline unused_type const*
+ begin(unused_type)
+ {
+ return &unused;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct end_container
+ {
+ static typename container_iterator<Container>::type call(Container& c)
+ {
+ return c.end();
+ }
+ };
+
+ template <typename Container>
+ inline typename container_iterator<Container>::type
+ end(Container& c)
+ {
+ return end_container<Container>::call(c);
+ }
+
+ inline unused_type const*
+ end(unused_type)
+ {
+ return &unused;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct deref_iterator
+ {
+ typedef typename boost::detail::iterator_traits<Iterator>::reference type;
+ static type call(Iterator& it)
+ {
+ return *it;
+ }
+ };
+
+ template <typename Iterator>
+ typename deref_iterator<Iterator>::type
+ deref(Iterator& it)
+ {
+ return deref_iterator<Iterator>::call(it);
+ }
+
+ inline unused_type
+ deref(unused_type const*)
+ {
+ return unused;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct next_iterator
+ {
+ static void call(Iterator& it)
+ {
+ ++it;
+ }
+ };
+
+ template <typename Iterator>
+ void next(Iterator& it)
+ {
+ next_iterator<Iterator>::call(it);
+ }
+
+ inline void next(unused_type const*)
+ {
+ // do nothing
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct compare_iterators
+ {
+ static bool call(Iterator const& it1, Iterator const& it2)
+ {
+ return it1 == it2;
+ }
+ };
+
+ template <typename Iterator>
+ bool compare(Iterator& it1, Iterator& it2)
+ {
+ return compare_iterators<Iterator>::call(it1, it2);
+ }
+
+ inline bool compare(unused_type const*, unused_type const*)
+ {
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct build_container : mpl::identity<std::vector<T>> {};
+
+ template <typename T>
+ struct build_container<boost::fusion::deque<T> > : build_container<T> {};
+
+ template <>
+ struct build_container<unused_type> : mpl::identity<unused_type> {};
+
+ template <>
+ struct build_container<char> : mpl::identity<std::string> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/handles_container.hpp b/boost/spirit/home/x3/support/traits/handles_container.hpp
new file mode 100644
index 0000000000..3fe05aef87
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/handles_container.hpp
@@ -0,0 +1,31 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2013 Agustin Berge
+
+ 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_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM)
+#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Whether a component handles container attributes intrinsically
+ // (or whether container attributes need to be split up separately).
+ // By default, this gets the Component's handles_container nested value.
+ // Components may specialize this if such a handles_container is not
+ // readily available (e.g. expensive to compute at compile time).
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct handles_container : mpl::bool_<Component::handles_container> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/has_attribute.hpp b/boost/spirit/home/x3/support/traits/has_attribute.hpp
new file mode 100644
index 0000000000..c8b1f8a347
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/has_attribute.hpp
@@ -0,0 +1,63 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
+#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Whether a component has an attribute. By default, this compares the
+ // component attribute against unused_type. If the component provides a
+ // nested constant expression has_attribute as a hint, that value is used
+ // instead. Components may specialize this.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct has_attribute;
+
+ namespace detail
+ {
+ template <typename Component, typename Context, typename Enable = void>
+ struct default_has_attribute
+ : mpl::not_<is_same<unused_type,
+ typename attribute_of<Component, Context>::type>> {};
+
+ template <typename Component, typename Context>
+ struct default_has_attribute<Component, Context,
+ typename disable_if_substitution_failure<
+ mpl::bool_<Component::has_attribute>>::type>
+ : mpl::bool_<Component::has_attribute> {};
+
+ template <typename Component, typename Context>
+ struct default_has_attribute<Component, Context,
+ typename enable_if_c<Component::is_pass_through_unary>::type>
+ : has_attribute<typename Component::subject_type, Context> {};
+ }
+
+ template <typename Component, typename Context, typename Enable>
+ struct has_attribute : detail::default_has_attribute<Component, Context> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_parser.hpp b/boost/spirit/home/x3/support/traits/is_parser.hpp
new file mode 100644
index 0000000000..cfbe8f74b4
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_parser.hpp
@@ -0,0 +1,37 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2014 Agustin Berge
+
+ 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_X3_IS_PARSER_MAY_20_2013_0235PM)
+#define BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // is_parser<T>: metafunction that evaluates to mpl::true_ if a type T
+ // can be used as a parser, mpl::false_ otherwise
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_parser
+ : mpl::false_
+ {};
+
+ template <typename T>
+ struct is_parser<T, typename disable_if_substitution_failure<
+ typename extension::as_parser<T>::type>::type>
+ : mpl::true_
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_substitute.hpp b/boost/spirit/home/x3/support/traits/is_substitute.hpp
new file mode 100644
index 0000000000..9e023371ce
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_substitute.hpp
@@ -0,0 +1,164 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)
+#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/map.hpp>
+#include <boost/fusion/include/value_at_key.hpp>
+#include <boost/fusion/adapted/mpl.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/equal.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/count_if.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Find out if T can be a (strong) substitute for Attribute
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Attribute, typename Enable = void>
+ struct is_substitute;
+
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute;
+
+ namespace detail
+ {
+ template <typename T, typename Attribute>
+ struct value_type_is_substitute
+ : is_substitute<
+ typename container_value<T>::type
+ , typename container_value<Attribute>::type>
+ {};
+
+ template <typename T, typename Attribute, typename Enable = void>
+ struct is_substitute_impl : is_same<T, Attribute> {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_sequence<Attribute>,
+ mpl::equal<T, Attribute, is_substitute<mpl::_1, mpl::_2>>
+ >
+ >::type>
+ : mpl::true_ {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ mpl::and_<
+ is_container<T>,
+ is_container<Attribute>,
+ value_type_is_substitute<T, Attribute>
+ >
+ >::type>
+ : mpl::true_ {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ is_variant<Attribute>
+ >::type>
+ : mpl::or_<
+ is_same<T, Attribute>
+ , variant_has_substitute<Attribute, T>
+ >
+ {};
+ }
+
+ template <typename T, typename Attribute, typename Enable /*= void*/>
+ struct is_substitute
+ : detail::is_substitute_impl<T, Attribute> {};
+
+ // for reference T
+ template <typename T, typename Attribute, typename Enable>
+ struct is_substitute<T&, Attribute, Enable>
+ : is_substitute<T, Attribute, Enable> {};
+
+ // for reference Attribute
+ template <typename T, typename Attribute, typename Enable>
+ struct is_substitute<T, Attribute&, Enable>
+ : is_substitute<T, Attribute, Enable> {};
+
+ // 2 element mpl tuple is compatible with fusion::map if:
+ // - it's first element type is existing key in map
+ // - it second element type is compatible to type stored at the key in map
+ template <typename T, typename Attribute>
+ struct is_substitute<T, Attribute
+ , typename enable_if<
+ typename mpl::eval_if<
+ mpl::and_<fusion::traits::is_sequence<T>
+ , fusion::traits::is_sequence<Attribute>>
+ , mpl::and_<traits::has_size<T, 2>
+ , fusion::traits::is_associative<Attribute>>
+ , mpl::false_>::type>::type>
+
+ {
+ // checking that "p_key >> p_value" parser can
+ // store it's result in fusion::map attribute
+ typedef typename mpl::at_c<T, 0>::type p_key;
+ typedef typename mpl::at_c<T, 1>::type p_value;
+
+ // for simple p_key type we just check that
+ // such key can be found in attr and that value under that key
+ // matches p_value
+ template <typename Key, typename Value, typename Map>
+ struct has_kv_in_map
+ : mpl::eval_if<
+ fusion::result_of::has_key<Map, Key>
+ , mpl::apply<
+ is_substitute<
+ fusion::result_of::value_at_key<mpl::_1, Key>
+ , Value>
+ , Map>
+ , mpl::false_>
+ {};
+
+ // if p_key is variant over multiple types (as a result of
+ // "(key1|key2|key3) >> p_value" parser) check that all
+ // keys are found in fusion::map attribute and that values
+ // under these keys match p_value
+ template <typename Variant>
+ struct variant_kv
+ : mpl::equal_to<
+ mpl::size< typename Variant::types>
+ , mpl::size< mpl::filter_view<typename Variant::types
+ , has_kv_in_map<mpl::_1, p_value, Attribute>>>
+ >
+ {};
+
+ typedef typename
+ mpl::eval_if<
+ is_variant<p_key>
+ , variant_kv<p_key>
+ , has_kv_in_map<p_key, p_value, Attribute>
+ >::type
+ type;
+ };
+
+ template <typename T, typename Attribute>
+ struct is_substitute<optional<T>, optional<Attribute>>
+ : is_substitute<T, Attribute> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_variant.hpp b/boost/spirit/home/x3/support/traits/is_variant.hpp
new file mode 100644
index 0000000000..829a673c3f
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_variant.hpp
@@ -0,0 +1,45 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_IS_VARIANT_JAN_10_2012_0823AM)
+#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ namespace detail
+ {
+ // By declaring a nested struct in your class/struct, you tell
+ // spirit that it is regarded as a variant type. The minimum
+ // required interface for such a variant is that it has constructors
+ // for various types supported by your variant and a typedef 'types'
+ // which is an mpl sequence of the contained types.
+ //
+ // This is an intrusive interface. For a non-intrusive interface,
+ // use the is_variant trait.
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
+ }
+
+ template <typename T, typename Enable = void>
+ struct is_variant
+ : detail::has_adapted_variant_tag<T>
+ {};
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
+ : mpl::true_
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/make_attribute.hpp b/boost/spirit/home/x3/support/traits/make_attribute.hpp
new file mode 100644
index 0000000000..cf3baeedaf
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/make_attribute.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2012 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM)
+#define BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Attribute>
+ struct make_attribute_base
+ {
+ static Attribute call(unused_type)
+ {
+ // synthesize the attribute/parameter
+ return Attribute();
+ }
+
+ template <typename T>
+ static T& call(T& value)
+ {
+ return value; // just pass the one provided
+ }
+ };
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute : make_attribute_base<Attribute>
+ {
+ typedef ActualAttribute& type;
+ typedef ActualAttribute value_type;
+ };
+
+ template <typename Attribute>
+ struct make_attribute<Attribute, unused_type>
+ : make_attribute_base<Attribute>
+ {
+ typedef typename remove_const<Attribute>::type attribute_type;
+ typedef attribute_type type;
+ typedef attribute_type value_type;
+ };
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute<Attribute&, ActualAttribute>
+ : make_attribute<Attribute, ActualAttribute> {};
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute<Attribute const&, ActualAttribute>
+ : make_attribute<Attribute const, ActualAttribute> {};
+
+ template <typename ActualAttribute>
+ struct make_attribute<unused_type, ActualAttribute>
+ {
+ typedef unused_type type;
+ typedef unused_type value_type;
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+ template <>
+ struct make_attribute<unused_type, unused_type>
+ {
+ typedef unused_type type;
+ typedef unused_type value_type;
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/move_to.hpp b/boost/spirit/home/x3/support/traits/move_to.hpp
new file mode 100644
index 0000000000..ecd7c6f202
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/move_to.hpp
@@ -0,0 +1,211 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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_X3_MOVE_TO_JAN_17_2013_0859PM)
+#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/move.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <utility>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Source, typename Dest>
+ void move_to(Source&& src, Dest& dest);
+
+ template <typename Dest>
+ inline void move_to(unused_type, Dest&) {}
+
+ template <typename Source>
+ inline void move_to(Source&, unused_type) {}
+
+ inline void move_to(unused_type, unused_type) {}
+
+ template <typename Iterator, typename Dest>
+ void
+ move_to(Iterator first, Iterator last, Dest& dest);
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator, Iterator, unused_type) {}
+
+ namespace detail
+ {
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&&, Dest&, unused_attribute) {}
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_plain(Source&& src, Dest& dest, mpl::false_) // src is not a single-element tuple
+ {
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple
+ {
+ dest = std::move(fusion::front(src));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, plain_attribute)
+ {
+ typename mpl::and_<
+ fusion::traits::is_sequence<Source>,
+ is_size_one_sequence<Source> >
+ is_single_element_sequence;
+
+ move_to_plain(std::move(src), dest, is_single_element_sequence);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<is_container<Source>>::type
+ move_to(Source&& src, Dest& dest, container_attribute)
+ {
+ traits::move_to(src.begin(), src.end(), dest);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<
+ mpl::and_<
+ is_same_size_sequence<Dest, Source>,
+ mpl::not_<is_size_one_sequence<Dest> > >
+ >::type
+ move_to(Source&& src, Dest& dest, tuple_attribute)
+ {
+ fusion::move(std::move(src), dest);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<
+ is_size_one_sequence<Dest>
+ >::type
+ move_to(Source&& src, Dest& dest, tuple_attribute)
+ {
+ traits::move_to(src, fusion::front(dest));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
+ {
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::false_)
+ {
+ // dest is a variant, src is a single element fusion sequence that the variant
+ // cannot directly hold. We'll try to unwrap the single element fusion sequence.
+
+ // Make sure that the Dest variant can really hold Source
+ static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
+ "Error! The destination variant (Dest) cannot hold the source type (Source)");
+
+ dest = std::move(fusion::front(src));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::true_)
+ {
+ // dest is a variant, src is a single element fusion sequence that the variant
+ // *can* directly hold.
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
+ {
+ move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute tag)
+ {
+ move_to(src, dest, tag, is_size_one_sequence<Source>());
+ }
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator, Iterator, unused_type, unused_attribute) {}
+
+ template <typename Iterator, typename Dest>
+ inline void
+ move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
+ {
+ if (is_empty(dest))
+ dest = Dest(first, last);
+ else
+ append(dest, first, last);
+ }
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
+ {
+ rng = {first, last};
+ }
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest)
+ {
+ detail::move_to(std::move(src), dest
+ , typename attribute_category<Dest>::type());
+ }
+
+ template <typename T>
+ inline void move_to(T& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename T>
+ inline void move_to(T const& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename T>
+ inline void move_to(T&& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename Iterator, typename Dest>
+ inline void
+ move_to(Iterator first, Iterator last, Dest& dest)
+ {
+ // $$$ Use std::move_iterator when iterator is not a const-iterator $$$
+ detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/numeric_traits.hpp b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
new file mode 100644
index 0000000000..3cdbdaec63
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
@@ -0,0 +1,128 @@
+/*=============================================================================
+ 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_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM)
+#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/integer_traits.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a boolean type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_bool : mpl::false_ {};
+
+ template <typename T>
+ struct is_bool<T const> : is_bool<T> {};
+
+ template <>
+ struct is_bool<bool> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a signed integer type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_int : mpl::false_ {};
+
+ template <typename T>
+ struct is_int<T const> : is_int<T> {};
+
+ template <>
+ struct is_int<short> : mpl::true_ {};
+
+ template <>
+ struct is_int<int> : mpl::true_ {};
+
+ template <>
+ struct is_int<long> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+ template <>
+ struct is_int<boost::long_long_type> : mpl::true_ {};
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is an unsigned integer type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_uint : mpl::false_ {};
+
+ template <typename T>
+ struct is_uint<T const> : is_uint<T> {};
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ template <>
+ struct is_uint<unsigned short> : mpl::true_ {};
+#endif
+
+ template <>
+ struct is_uint<unsigned int> : mpl::true_ {};
+
+ template <>
+ struct is_uint<unsigned long> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+ template <>
+ struct is_uint<boost::ulong_long_type> : mpl::true_ {};
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a floating point type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_real : mpl::false_ {};
+
+ template <typename T>
+ struct is_real<T const> : is_uint<T> {};
+
+ template <>
+ struct is_real<float> : mpl::true_ {};
+
+ template <>
+ struct is_real<double> : mpl::true_ {};
+
+ template <>
+ struct is_real<long double> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // customization points for numeric operations
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct absolute_value;
+
+ template <typename T, typename Enable = void>
+ struct is_negative;
+
+ template <typename T, typename Enable = void>
+ struct is_zero;
+
+ template <typename T, typename Enable = void>
+ struct pow10_helper;
+
+ template <typename T, typename Enable = void>
+ struct is_nan;
+
+ template <typename T, typename Enable = void>
+ struct is_infinite;
+
+ template <typename T, typename Enable = void>
+ struct check_overflow : mpl::false_ {};
+
+ template <typename T>
+ struct check_overflow<T, typename enable_if_c<integer_traits<T>::is_integral>::type>
+ : mpl::true_ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/optional_traits.hpp b/boost/spirit/home/x3/support/traits/optional_traits.hpp
new file mode 100644
index 0000000000..65568b0265
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/optional_traits.hpp
@@ -0,0 +1,78 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)
+#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_optional
+ : mpl::false_
+ {};
+
+ template <typename T>
+ struct is_optional<boost::optional<T>>
+ : mpl::true_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_optional
+ //
+ // Build a boost::optional from T. Return unused_type if T is unused_type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct build_optional
+ {
+ typedef boost::optional<T> type;
+ };
+
+ template <typename T>
+ struct build_optional<boost::optional<T> >
+ {
+ typedef boost::optional<T> type;
+ };
+
+ template <>
+ struct build_optional<unused_type>
+ {
+ typedef unused_type type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // optional_value
+ //
+ // Get the optional's value_type. Handles unused_type as well.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct optional_value : mpl::identity<T> {};
+
+ template <typename T>
+ struct optional_value<boost::optional<T> >
+ : mpl::identity<T> {};
+
+ template <>
+ struct optional_value<unused_type>
+ : mpl::identity<unused_type> {};
+
+ template <>
+ struct optional_value<unused_type const>
+ : mpl::identity<unused_type> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/print_attribute.hpp b/boost/spirit/home/x3/support/traits/print_attribute.hpp
new file mode 100644
index 0000000000..47bffce1a1
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/print_attribute.hpp
@@ -0,0 +1,150 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ 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_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
+#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Out, typename T>
+ void print_attribute(Out& out, T const& val);
+
+ template <typename Out>
+ inline void print_attribute(Out&, unused_type) {}
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename Out>
+ struct print_fusion_sequence
+ {
+ print_fusion_sequence(Out& out)
+ : out(out), is_first(true) {}
+
+ typedef void result_type;
+
+ template <typename T>
+ void operator()(T const& val) const
+ {
+ if (is_first)
+ is_first = false;
+ else
+ out << ", ";
+ x3::traits::print_attribute(out, val);
+ }
+
+ Out& out;
+ mutable bool is_first;
+ };
+
+ // print elements in a variant
+ template <typename Out>
+ struct print_visitor : static_visitor<>
+ {
+ print_visitor(Out& out) : out(out) {}
+
+ template <typename T>
+ void operator()(T const& val) const
+ {
+ x3::traits::print_attribute(out, val);
+ }
+
+ Out& out;
+ };
+ }
+
+ template <typename Out, typename T, typename Enable = void>
+ struct print_attribute_debug
+ {
+ // for plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, unused_attribute)
+ {
+ out << "unused";
+ }
+
+ // for plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, plain_attribute)
+ {
+ out << val;
+ }
+
+ // for fusion data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, tuple_attribute)
+ {
+ out << '[';
+ fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
+ out << ']';
+ }
+
+ // stl container
+ template <typename T_>
+ static void call(Out& out, T_ const& val, container_attribute)
+ {
+ out << '[';
+ if (!traits::is_empty(val))
+ {
+ bool first = true;
+ typename container_iterator<T_ const>::type iend = traits::end(val);
+ for (typename container_iterator<T_ const>::type i = traits::begin(val);
+ !traits::compare(i, iend); traits::next(i))
+ {
+ if (!first)
+ out << ", ";
+ first = false;
+ x3::traits::print_attribute(out, traits::deref(i));
+ }
+ }
+ out << ']';
+ }
+
+ // for variant types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, variant_attribute)
+ {
+ apply_visitor(detail::print_visitor<Out>(out), val);
+ }
+
+ // for optional types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, optional_attribute)
+ {
+ if (val)
+ x3::traits::print_attribute(out, *val);
+ else
+ out << "[empty]";
+ }
+
+ // main entry point
+ static void call(Out& out, T const& val)
+ {
+ call(out, val, typename attribute_category<T>::type());
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Out, typename T>
+ inline void print_attribute(Out& out, T const& val)
+ {
+ print_attribute_debug<Out, T>::call(out, val);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/print_token.hpp b/boost/spirit/home/x3/support/traits/print_token.hpp
new file mode 100644
index 0000000000..f1429f4776
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/print_token.hpp
@@ -0,0 +1,79 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ 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_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)
+#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <cctype>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // generate debug output for lookahead token (character) stream
+ namespace detail
+ {
+ struct token_printer_debug_for_chars
+ {
+ template<typename Out, typename Char>
+ static void print(Out& o, Char c)
+ {
+ using namespace std; // allow for ADL to find the proper iscntrl
+
+ switch (c)
+ {
+ case '\a': o << "\\a"; break;
+ case '\b': o << "\\b"; break;
+ case '\f': o << "\\f"; break;
+ case '\n': o << "\\n"; break;
+ case '\r': o << "\\r"; break;
+ case '\t': o << "\\t"; break;
+ case '\v': o << "\\v"; break;
+ default:
+ if (c >= 0 && c < 127 && iscntrl(c))
+ o << "\\" << std::oct << int(c);
+ else
+ o << Char(c);
+ }
+ }
+ };
+
+ // for token types where the comparison with char constants wouldn't work
+ struct token_printer_debug
+ {
+ template<typename Out, typename T>
+ static void print(Out& o, T const& val)
+ {
+ o << val;
+ }
+ };
+ }
+
+ template <typename T, typename Enable = void>
+ struct token_printer_debug
+ : mpl::if_<
+ mpl::and_<
+ is_convertible<T, char>, is_convertible<char, T> >
+ , detail::token_printer_debug_for_chars
+ , detail::token_printer_debug>::type
+ {};
+
+ template <typename Out, typename T>
+ inline void print_token(Out& out, T const& val)
+ {
+ // allow to customize the token printer routine
+ token_printer_debug<T>::print(out, val);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/string_traits.hpp b/boost/spirit/home/x3/support/traits/string_traits.hpp
new file mode 100644
index 0000000000..46ee356cdc
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/string_traits.hpp
@@ -0,0 +1,291 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
+
+ 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_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
+#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <string>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a character type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_char : mpl::false_ {};
+
+ template <typename T>
+ struct is_char<T const> : is_char<T> {};
+
+ template <>
+ struct is_char<char> : mpl::true_ {};
+
+ template <>
+ struct is_char<wchar_t> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_string : mpl::false_ {};
+
+ template <typename T>
+ struct is_string<T const> : is_string<T> {};
+
+ template <>
+ struct is_string<char const*> : mpl::true_ {};
+
+ template <>
+ struct is_string<wchar_t const*> : mpl::true_ {};
+
+ template <>
+ struct is_string<char*> : mpl::true_ {};
+
+ template <>
+ struct is_string<wchar_t*> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char const[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t const[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char const(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
+
+ template <typename T, typename Traits, typename Allocator>
+ struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the underlying char type of a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct char_type_of;
+
+ template <typename T>
+ struct char_type_of<T const> : char_type_of<T> {};
+
+ template <>
+ struct char_type_of<char> : mpl::identity<char> {};
+
+ template <>
+ struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
+
+ template <>
+ struct char_type_of<char const*> : mpl::identity<char const> {};
+
+ template <>
+ struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
+
+ template <>
+ struct char_type_of<char*> : mpl::identity<char> {};
+
+ template <>
+ struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char[N]> : mpl::identity<char> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char const[N]> : mpl::identity<char const> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
+
+ template <std::size_t N>
+ struct char_type_of<char(&)[N]> : mpl::identity<char> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
+
+ template <typename T, typename Traits, typename Allocator>
+ struct char_type_of<std::basic_string<T, Traits, Allocator> >
+ : mpl::identity<T> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the C string from a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename String>
+ struct extract_c_string;
+
+ template <typename String>
+ struct extract_c_string
+ {
+ typedef typename char_type_of<String>::type char_type;
+
+ template <typename T>
+ static T const* call (T* str)
+ {
+ return (T const*)str;
+ }
+
+ template <typename T>
+ static T const* call (T const* str)
+ {
+ return str;
+ }
+ };
+
+ // Forwarder that strips const
+ template <typename T>
+ struct extract_c_string<T const>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T const str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ // Forwarder that strips references
+ template <typename T>
+ struct extract_c_string<T&>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T& str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ // Forwarder that strips const references
+ template <typename T>
+ struct extract_c_string<T const&>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T const& str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ template <typename T, typename Traits, typename Allocator>
+ struct extract_c_string<std::basic_string<T, Traits, Allocator> >
+ {
+ typedef T char_type;
+
+ typedef std::basic_string<T, Traits, Allocator> string;
+
+ static T const* call (string const& str)
+ {
+ return str.c_str();
+ }
+ };
+
+ template <typename T>
+ typename extract_c_string<T*>::char_type const*
+ get_c_string(T* str)
+ {
+ return extract_c_string<T*>::call(str);
+ }
+
+ template <typename T>
+ typename extract_c_string<T const*>::char_type const*
+ get_c_string(T const* str)
+ {
+ return extract_c_string<T const*>::call(str);
+ }
+
+ template <typename String>
+ typename extract_c_string<String>::char_type const*
+ get_c_string(String& str)
+ {
+ return extract_c_string<String>::call(str);
+ }
+
+ template <typename String>
+ typename extract_c_string<String>::char_type const*
+ get_c_string(String const& str)
+ {
+ return extract_c_string<String>::call(str);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the begin/end iterators from a string
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Implementation for C-style strings.
+
+ template <typename T>
+ inline T const* get_string_begin(T const* str) { return str; }
+
+ template <typename T>
+ inline T* get_string_begin(T* str) { return str; }
+
+ template <typename T>
+ inline T const* get_string_end(T const* str)
+ {
+ T const* last = str;
+ while (*last)
+ last++;
+ return last;
+ }
+
+ template <typename T>
+ inline T* get_string_end(T* str)
+ {
+ T* last = str;
+ while (*last)
+ last++;
+ return last;
+ }
+
+ // Implementation for containers (includes basic_string).
+ template <typename T, typename Str>
+ inline typename Str::const_iterator get_string_begin(Str const& str)
+ { return str.begin(); }
+
+ template <typename T, typename Str>
+ inline typename Str::iterator
+ get_string_begin(Str& str)
+ { return str.begin(); }
+
+ template <typename T, typename Str>
+ inline typename Str::const_iterator get_string_end(Str const& str)
+ { return str.end(); }
+
+ template <typename T, typename Str>
+ inline typename Str::iterator
+ get_string_end(Str& str)
+ { return str.end(); }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/transform_attribute.hpp b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
new file mode 100644
index 0000000000..24268520d7
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2012 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // transform_attribute
+ //
+ // Sometimes the user needs to transform the attribute types for certain
+ // attributes. This template can be used as a customization point, where
+ // the user is able specify specific transformation rules for any attribute
+ // type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Exposed, typename Transformed, typename Tag
+ , typename Enable = void>
+ struct transform_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Tag, typename Transformed, typename Exposed>
+ typename transform_attribute<Exposed, Transformed, Tag>::type
+ pre_transform(Exposed& attr)
+ {
+ return transform_attribute<Exposed, Transformed, Tag>::pre(attr);
+ }
+
+ template <typename Tag, typename Transformed, typename Exposed>
+ typename transform_attribute<Exposed, Transformed, Tag>::type
+ pre_transform(Exposed const& attr)
+ {
+ return transform_attribute<Exposed const, Transformed, Tag>::pre(attr);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/tuple_traits.hpp b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
new file mode 100644
index 0000000000..17bfd4e1cb
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ 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_X3_TUPLE_TRAITS_JANUARY_2012_1132PM)
+#define BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename A, typename B>
+ struct has_same_size
+ : mpl::bool_<(
+ fusion::result_of::size<A>::value ==
+ fusion::result_of::size<B>::value
+ )>
+ {};
+
+ template <typename T, std::size_t N>
+ struct has_size
+ : mpl::bool_<(fusion::result_of::size<T>::value == N)>
+ {};
+
+ template <typename A, typename B>
+ struct is_same_size_sequence
+ : mpl::and_<
+ fusion::traits::is_sequence<A>
+ , fusion::traits::is_sequence<B>
+ , has_same_size<A, B>
+ >
+ {};
+
+ template <typename Seq>
+ struct is_size_one_sequence
+ : mpl::and_<
+ fusion::traits::is_sequence<Seq>
+ , has_size<Seq, 1>
+ >
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/value_traits.hpp b/boost/spirit/home/x3/support/traits/value_traits.hpp
new file mode 100644
index 0000000000..5f004c957c
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/value_traits.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
+#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/utility/value_init.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename T, typename Enable = void>
+ struct value_initialize
+ {
+ static T call()
+ {
+ return boost::value_initialized<T>();
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
new file mode 100644
index 0000000000..4de7b7d5e3
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM)
+#define BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Variant, typename Attribute>
+ struct variant_find_substitute
+ {
+ // Get the type from the variant that can be a substitute for Attribute.
+ // If none is found, just return Attribute
+
+ typedef Variant variant_type;
+ typedef typename variant_type::types types;
+ typedef typename mpl::end<types>::type end;
+
+ typedef typename
+ mpl::find_if<types, is_same<mpl::_1, Attribute> >::type
+ iter_1;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter_1, end>,
+ mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
+ mpl::identity<iter_1>
+ >::type
+ iter;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter, end>,
+ mpl::identity<Attribute>,
+ mpl::deref<iter>
+ >::type
+ type;
+ };
+
+ template <typename Variant>
+ struct variant_find_substitute<Variant, Variant>
+ : mpl::identity<Variant> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
new file mode 100644
index 0000000000..d0dfb49b8d
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM)
+#define BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute_impl
+ {
+ // Find a type from the variant that can be a substitute for Attribute.
+ // return true_ if one is found, else false_
+
+ typedef Variant variant_type;
+ typedef typename variant_type::types types;
+ typedef typename mpl::end<types>::type end;
+
+ typedef typename
+ mpl::find_if<types, is_same<mpl::_1, Attribute>>::type
+ iter_1;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter_1, end>,
+ mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
+ mpl::identity<iter_1>
+ >::type
+ iter;
+
+ typedef mpl::not_<is_same<iter, end>> type;
+ };
+
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute
+ : variant_has_substitute_impl<Variant, Attribute>::type {};
+
+ template <typename Attribute>
+ struct variant_has_substitute<unused_type, Attribute> : mpl::true_ {};
+
+ template <typename Attribute>
+ struct variant_has_substitute<unused_type const, Attribute> : mpl::true_ {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/unused.hpp b/boost/spirit/home/x3/support/unused.hpp
new file mode 100644
index 0000000000..cf42d13098
--- /dev/null
+++ b/boost/spirit/home/x3/support/unused.hpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ 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_X3_UNUSED_APRIL_16_2006_0616PM)
+#define BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <ostream>
+#include <istream>
+#include <boost/mpl/identity.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4522) // multiple assignment operators specified warning
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type
+ {
+ unused_type()
+ {
+ }
+
+ template <typename T>
+ unused_type(T const&)
+ {
+ }
+
+ template <typename T>
+ unused_type const&
+ operator=(T const&) const
+ {
+ return *this;
+ }
+
+ template <typename T>
+ unused_type&
+ operator=(T const&)
+ {
+ return *this;
+ }
+
+ unused_type const&
+ operator=(unused_type const&) const
+ {
+ return *this;
+ }
+
+ unused_type&
+ operator=(unused_type const&)
+ {
+ return *this;
+ }
+
+ // unused_type can also masquerade as an empty context (see context.hpp)
+
+ template <typename ID>
+ struct get_result : mpl::identity<unused_type> {};
+
+ template <typename ID>
+ unused_type get(ID) const
+ {
+ return unused_type();
+ }
+ };
+
+ unused_type const unused = unused_type();
+
+ inline std::ostream& operator<<(std::ostream& out, unused_type const&)
+ {
+ return out;
+ }
+
+ inline std::istream& operator>>(std::istream& in, unused_type&)
+ {
+ return in;
+ }
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/detail/testing.hpp b/boost/spirit/home/x3/support/utility/detail/testing.hpp
new file mode 100644
index 0000000000..1423d9fc7b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/detail/testing.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+ Copyright (c) 2014 Joel de Guzman
+
+ 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_X3_DETAIL_TESTING_JUNE_05_2014_00422PM)
+#define BOOST_SPIRIT_X3_DETAIL_TESTING_JUNE_05_2014_00422PM
+
+namespace boost { namespace spirit { namespace x3 { namespace testing
+{
+
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/error_reporting.hpp b/boost/spirit/home/x3/support/utility/error_reporting.hpp
new file mode 100644
index 0000000000..9e65f2149b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/error_reporting.hpp
@@ -0,0 +1,241 @@
+/*=============================================================================
+ Copyright (c) 2014 Joel de Guzman
+
+ 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_X3_ERROR_REPORTING_MAY_19_2014_00405PM)
+#define BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM
+
+#include <boost/filesystem/path.hpp>
+#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
+#include <ostream>
+
+// Clang-style error handling utilities
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Iterator>
+ class error_handler
+ {
+ public:
+
+ typedef Iterator iterator_type;
+
+ error_handler(
+ Iterator first, Iterator last, std::ostream& err_out
+ , std::string file = "", int tabs = 4)
+ : err_out(err_out)
+ , file(file)
+ , tabs(tabs)
+ , pos_cache(first, last) {}
+
+ typedef void result_type;
+
+ void operator()(Iterator err_pos, std::string const& error_message) const;
+ void operator()(Iterator err_first, Iterator err_last, std::string const& error_message) const;
+ void operator()(position_tagged pos, std::string const& message) const
+ {
+ auto where = pos_cache.position_of(pos);
+ (*this)(
+ where.begin()
+ , where.end()
+ , message
+ );
+ }
+
+ template <typename AST>
+ void tag(AST& ast, Iterator first, Iterator last)
+ {
+ return pos_cache.annotate(ast, first, last);
+ }
+//
+// void operator()(
+// Iterator first
+// , Iterator last
+// , Iterator err_op
+// , Iterator err_first
+// , Iterator err_last
+// , std::string const& error_message
+// ) const;
+
+ private:
+
+ void print_file_line(std::size_t line) const;
+ void print_line(Iterator& line_start, Iterator last) const;
+ void print_indicator(Iterator& line_start, Iterator last, char ind) const;
+ void skip_whitespace(Iterator& err_pos, Iterator last) const;
+ void skip_non_whitespace(Iterator& err_pos, Iterator last) const;
+ Iterator get_line_start(Iterator first, Iterator pos) const;
+ std::size_t position(Iterator i) const;
+
+ std::ostream& err_out;
+ std::string file;
+ int tabs;
+ position_cache<std::vector<Iterator>> pos_cache;
+ };
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_file_line(std::size_t line) const
+ {
+ namespace fs = boost::filesystem;
+
+ if (file != "")
+ err_out << "In file " << fs::path(file).generic_string() << ", ";
+ else
+ err_out << "In ";
+
+ err_out << "line " << line << ':' << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_line(Iterator& start, Iterator last) const
+ {
+ for (; start != last; ++start)
+ {
+ auto c = *start;
+ if (c == '\r' || c == '\n')
+ break;
+ else
+ err_out << c;
+ }
+ err_out << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_indicator(Iterator& start, Iterator last, char ind) const
+ {
+ for (; start != last; ++start)
+ {
+ auto c = *start;
+ if (c == '\r' || c == '\n')
+ break;
+ else if (c == '\t')
+ for (int i = 0; i < tabs; ++i)
+ err_out << ind;
+ else
+ err_out << ind;
+ }
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::skip_whitespace(Iterator& err_pos, Iterator last) const
+ {
+ // make sure err_pos does not point to white space
+ while (err_pos != last)
+ {
+ char c = *err_pos;
+ if (std::isspace(c))
+ ++err_pos;
+ else
+ break;
+ }
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::skip_non_whitespace(Iterator& err_pos, Iterator last) const
+ {
+ // make sure err_pos does not point to white space
+ while (err_pos != last)
+ {
+ char c = *err_pos;
+ if (std::isspace(c))
+ break;
+ else
+ ++err_pos;
+ }
+ }
+
+ template <class Iterator>
+ inline Iterator error_handler<Iterator>::get_line_start(Iterator first, Iterator pos) const
+ {
+ Iterator latest = first;
+ for (Iterator i = first; i != pos; ++i)
+ if (*i == '\r' || *i == '\n')
+ latest = i;
+ return latest;
+ }
+
+ template <typename Iterator>
+ std::size_t error_handler<Iterator>::position(Iterator i) const
+ {
+ // $$$ asumes iterator is similar to line_pos_iterator $$$
+ return i.position();
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::operator()(
+ Iterator err_pos, std::string const& error_message) const
+ {
+ Iterator first = pos_cache.first();
+ Iterator last = pos_cache.last();
+
+ // make sure err_pos does not point to white space
+ skip_whitespace(err_pos, last);
+
+ print_file_line(position(err_pos));
+ err_out << error_message << std::endl;
+
+ Iterator start = get_line_start(first, err_pos);
+ if (start != first)
+ ++start;
+ Iterator i = start;
+ print_line(i, last);
+ print_indicator(start, err_pos, '_');
+ err_out << "^_" << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::operator()(
+ Iterator err_first, Iterator err_last, std::string const& error_message) const
+ {
+ Iterator first = pos_cache.first();
+ Iterator last = pos_cache.last();
+
+ // make sure err_pos does not point to white space
+ skip_whitespace(err_first, last);
+
+ print_file_line(position(err_first));
+ err_out << error_message << std::endl;
+
+ Iterator start = get_line_start(first, err_first);
+ if (start != first)
+ ++start;
+ Iterator i = start;
+ print_line(i, last);
+ print_indicator(start, err_first, ' ');
+ print_indicator(start, err_last, '~');
+ err_out << " <<-- Here" << std::endl;
+ }
+//
+// template <typename Iterator>
+// void error_handler<Iterator>::operator()(
+// Iterator first
+// , Iterator last
+// , Iterator err_op
+// , Iterator err_first
+// , Iterator err_last
+// , std::string const& error_message
+// ) const
+// {
+// // make sure err_pos does not point to white space
+// skip_whitespace(err_first, last);
+//
+// print_file_line(position(err_pos));
+// err_out << error_message << std::endl;
+//
+// Iterator start = get_line_start(first, err_first);
+// if (start != first)
+// ++start;
+// Iterator i = start;
+// print_line(i, last);
+// print_indicator(start, err_first, ' ');
+// print_indicator(start, err_op, '~');
+// err_out << '^';
+// print_indicator(++start, err_last, '~');
+// err_out << " <<-- Here" << std::endl;
+// }
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/integer_sequence.hpp b/boost/spirit/home/x3/support/utility/integer_sequence.hpp
new file mode 100644
index 0000000000..1f0bace72b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/integer_sequence.hpp
@@ -0,0 +1,94 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <cstddef>
+#include <boost/type_traits/integral_constant.hpp>
+
+// This is a standard (c++1y) compatible integer_sequence implementation,
+// it's needed for now, and it could be replaced with std::integer_sequence
+// once the new standard is available everywhere.
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, T... Ns>
+ struct integer_sequence
+ {
+ typedef T value_type;
+
+ static constexpr std::size_t size() noexcept
+ {
+ return sizeof...(Ns);
+ }
+ };
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename T, typename S1, typename S2, T N>
+ struct accum_integer_sequence;
+
+ template <typename T, T... N1, T... N2, T N>
+ struct accum_integer_sequence<T, integer_sequence<T, N1...>, integer_sequence<T, N2...>, N>
+ {
+ typedef integer_sequence<T, N1..., (N + N2)...> type;
+ };
+
+ template <typename N>
+ struct make_integer_sequence_impl
+ {
+ typedef typename N::value_type T;
+ static T const n = N::value;
+ static T const m = n / 2;
+ typedef typename
+ make_integer_sequence_impl<integral_constant<T, m>>::type
+ part1;
+ typedef typename
+ make_integer_sequence_impl<integral_constant<T, n - m>>::type
+ part2;
+ typedef typename
+ accum_integer_sequence<T, part1, part2, m>::type
+ type;
+ };
+
+ template <typename T>
+ struct make_integer_sequence_impl<integral_constant<T, 0>>
+ {
+ typedef integer_sequence<T> type;
+ };
+
+ template <typename T>
+ struct make_integer_sequence_impl<integral_constant<T, 1>>
+ {
+ typedef integer_sequence<T, 0> type;
+ };
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <std::size_t... Ns>
+ using index_sequence = integer_sequence<std::size_t, Ns...>;
+
+ template <typename T, T N>
+ using make_integer_sequence = typename detail::make_integer_sequence_impl<
+ integral_constant<T, N>>::type;
+
+ template <std::size_t N>
+ using make_index_sequence = make_integer_sequence<std::size_t, N>;
+
+ template <typename... T>
+ using index_sequence_for = make_index_sequence<sizeof...(T)>;
+}}}
+
+
+#endif
+
diff --git a/boost/spirit/home/x3/support/utility/is_callable.hpp b/boost/spirit/home/x3/support/utility/is_callable.hpp
new file mode 100644
index 0000000000..17f86822b8
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/is_callable.hpp
@@ -0,0 +1,45 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/utility/result_of.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Sig, typename Enable = void>
+ struct is_callable_impl
+ : mpl::false_
+ {};
+
+ template <typename F, typename... A>
+ struct is_callable_impl<F(A...), typename disable_if_substitution_failure<
+ typename result_of<F(A...)>::type>::type>
+ : mpl::true_
+ {};
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Sig>
+ struct is_callable;
+
+ template <typename F, typename... A>
+ struct is_callable<F(A...)>
+ : detail::is_callable_impl<F(A...)>
+ {};
+}}}
+
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/lambda_visitor.hpp b/boost/spirit/home/x3/support/utility/lambda_visitor.hpp
new file mode 100644
index 0000000000..83e1d2f046
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/lambda_visitor.hpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2014 Joel de Guzman
+
+ 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_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM)
+#define BOOST_SPIRIT_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename RT, typename... Lambdas>
+ struct lambda_visitor;
+
+ template <typename RT, typename F, typename... Lambdas>
+ struct lambda_visitor<RT, F, Lambdas...> : F, lambda_visitor<RT, Lambdas...>
+ {
+ typedef lambda_visitor<RT , Lambdas...> base_type;
+ using F::operator();
+ using base_type::operator();
+ lambda_visitor(F f, Lambdas... lambdas)
+ : F(f), base_type(lambdas...)
+ {}
+ };
+
+ template <typename RT, typename F>
+ struct lambda_visitor<RT, F> : F
+ {
+ typedef RT result_type;
+ using F::operator();
+ lambda_visitor(F f)
+ : F(f)
+ {}
+ };
+
+ template <typename RT>
+ struct lambda_visitor<RT>
+ {
+ typedef RT result_type;
+ };
+
+ template <typename RT, typename... Lambdas>
+ lambda_visitor<RT, Lambdas...> make_lambda_visitor(Lambdas... lambdas)
+ {
+ return { lambdas... };
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/sfinae.hpp b/boost/spirit/home/x3/support/utility/sfinae.hpp
new file mode 100644
index 0000000000..6cefa95961
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/sfinae.hpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+
+ 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_X3_SFINAE_MAY_20_2013_0840AM)
+#define BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Expr, typename T = void>
+ struct disable_if_substitution_failure
+ {
+ typedef T type;
+ };
+ template <typename Expr, typename T>
+ struct lazy_disable_if_substitution_failure
+ {
+ typedef typename T::type type;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/testing.hpp b/boost/spirit/home/x3/support/utility/testing.hpp
new file mode 100644
index 0000000000..fced46bef8
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/testing.hpp
@@ -0,0 +1,69 @@
+/*=============================================================================
+ Copyright (c) 2014 Joel de Guzman
+
+ 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_X3_TESTING_JUNE_05_2014_00422PM)
+#define BOOST_SPIRIT_X3_TESTING_JUNE_05_2014_00422PM
+
+namespace boost { namespace spirit { namespace x3 { namespace testing
+{
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Test utility
+ //
+ // The test function accepts a file loaded in memory. The 'test_file'
+ // range param points to the data contained in the file. This file
+ // contains two parts.
+ //
+ // 1) The source input for testing
+ // 2) The expected result.
+ //
+ // The first part of the file is sent to the generator function
+ // 'gen' which returns a string. This generated string is then compared
+ // to the contents of the second (expected result) part.
+ //
+ // The second part is demarcated by the string parameter 'demarcation'
+ // which defaults to "<**expected**>". The expected template may include
+ // embedded regular expressions marked-up within re_prefix and re_suffix
+ // parameter tags. For example, given the default RE markup ("<%" and
+ // "%>"), this template:
+ //
+ // <%[0-9]+%>
+ //
+ // will match any integer in the source input being tested. The function
+ // will return the first non-matching position. The flag full_match
+ // indicates a full match. It is possible for returned pos to be
+ // at the end of in (in.end()) while still returning full_match ==
+ // false. In that case, we have a partial match.
+ //
+ // Here's an example of a test file:
+ //
+ // Hello World, I am Joel. This is a test.
+ //
+ // <**expected**>
+ // Hello World, I am <%[a-zA-Z]+%>. This is a test.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ template <typename Iterator>
+ struct test_result
+ {
+ Iterator pos;
+ bool full_match;
+ };
+
+ template <typename Range, typename F>
+ test_result<typename Range::const_iterator>
+ test(
+ Range test_file
+ , F gen
+ , char const* demarcation = "<**expected**>"
+ , char const* re_prefix = "<%"
+ , char const* re_suffix = "%>"
+ );
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/unrefcv.hpp b/boost/spirit/home/x3/support/utility/unrefcv.hpp
new file mode 100644
index 0000000000..fa4d448178
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/unrefcv.hpp
@@ -0,0 +1,29 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T>
+ struct unrefcv : remove_cv<typename remove_reference<T>::type> {};
+
+ template <typename T>
+ using unrefcv_t = typename unrefcv<T>::type;
+}}}
+
+
+#endif
+
diff --git a/boost/spirit/home/x3/support/utility/utf8.hpp b/boost/spirit/home/x3/support/utility/utf8.hpp
new file mode 100644
index 0000000000..93b5a22077
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/utf8.hpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ 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_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)
+#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/foreach.hpp>
+#include <boost/regex/pending/unicode_iterator.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3
+{
+ typedef ::boost::uint32_t ucs4_char;
+ typedef char utf8_char;
+ typedef std::basic_string<ucs4_char> ucs4_string;
+ typedef std::basic_string<utf8_char> utf8_string;
+
+ template <typename Char>
+ inline utf8_string to_utf8(Char value)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ *utf8_iter = (UChar)value;
+ return result;
+ }
+
+ template <typename Char>
+ inline utf8_string to_utf8(Char const* str)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ while (*str)
+ *utf8_iter++ = (UChar)*str++;
+ return result;
+ }
+
+ template <typename Char, typename Traits, typename Allocator>
+ inline utf8_string
+ to_utf8(std::basic_string<Char, Traits, Allocator> const& str)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ BOOST_FOREACH(Char ch, str)
+ {
+ *utf8_iter++ = (UChar)ch;
+ }
+ return result;
+ }
+}}}
+
+#endif