add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
/*=============================================================================
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>
#include <boost/core/enable_if.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>
typename boost::enable_if_c<
(!is_base_of<position_tagged, AST>::value)
, boost::iterator_range<iterator_type>
>::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

View File

@@ -0,0 +1,265 @@
/*=============================================================================
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
#include <boost/config.hpp>
#include <boost/variant.hpp>
#include <boost/mpl/list.hpp>
#include <utility>
#include <type_traits>
///////////////////////////////////////////////////////////////////////////////
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) BOOST_NOEXCEPT
: 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) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
{
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) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
{
assign(rhs);
return *this;
}
forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
{
swap(rhs);
return *this;
}
forward_ast& operator=(T&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<T>::value)
{
get() = std::move(rhs);
return *this;
}
T& get() BOOST_NOEXCEPT { return *get_pointer(); }
const T& get() const BOOST_NOEXCEPT { return *get_pointer(); }
T* get_pointer() BOOST_NOEXCEPT { return p_; }
const T* get_pointer() const BOOST_NOEXCEPT { return p_; }
operator T const&() const BOOST_NOEXCEPT { return this->get(); }
operator T&() BOOST_NOEXCEPT { return this->get(); }
private:
void assign(const T& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
{
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>
{};
}
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4521) // multiple copy constructors specified
#endif
template <typename ...Types>
struct variant
{
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
using variant_type = boost::variant<Types...>;
using types = mpl::list<typename detail::remove_forward<Types>::type...>;
using base_type = variant; // The current instantiation
template<typename T>
using non_self_t // used only for SFINAE checks below
= std::enable_if_t<!(std::is_base_of<base_type
,std::remove_reference_t<T>
>
::value)
>;
variant() BOOST_NOEXCEPT_IF(std::is_nothrow_default_constructible<variant_type>::value) : var() {}
template <typename T, class = non_self_t<T>>
explicit variant(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T const&>::value))
: var(rhs) {}
template <typename T, class = non_self_t<T>>
explicit variant(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T&&>::value))
: var(std::forward<T>(rhs)) {}
variant(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_constructible<variant_type>::value)
: var(rhs.var) {}
variant(variant& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, variant_type&>::value))
: var(rhs.var) {}
variant(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_constructible<variant_type>::value)
: var(std::move(rhs.var)) {}
variant& operator=(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<variant_type>::value)
{
var = rhs.get();
return *this;
}
variant& operator=(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<variant_type>::value)
{
var = std::move(rhs.get());
return *this;
}
template <typename T, class = non_self_t<T>>
variant& operator=(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T const&>::value))
{
var = rhs;
return *this;
}
template <typename T, class = non_self_t<T>>
variant& operator=(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T&&>::value))
{
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 BOOST_NOEXCEPT
{
return var;
}
variant_type& get() BOOST_NOEXCEPT
{
return var;
}
void swap(variant& rhs) BOOST_NOEXCEPT
{
var.swap(rhs.var);
}
variant_type var;
};
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
}}}
namespace boost
{
template <typename T, typename ...Types>
inline T const&
get(boost::spirit::x3::variant<Types...> const& x) BOOST_NOEXCEPT
{
return boost::get<T>(x.get());
}
template <typename T, typename ...Types>
inline T&
get(boost::spirit::x3::variant<Types...>& x) BOOST_NOEXCEPT
{
return boost::get<T>(x.get());
}
template <typename T, typename ...Types>
inline T const*
get(boost::spirit::x3::variant<Types...> const* x) BOOST_NOEXCEPT
{
return boost::get<T>(&x->get());
}
template <typename T, typename ...Types>
inline T*
get(boost::spirit::x3::variant<Types...>* x) BOOST_NOEXCEPT
{
return boost::get<T>(&x->get());
}
}
#endif

View File

@@ -0,0 +1,103 @@
/*=============================================================================
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
#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) {}
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
decltype(auto) 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) {}
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
unused_type get(ID_) const
{
return {};
}
T& val;
};
template <typename Tag, typename Context>
inline decltype(auto) get(Context const& context)
{
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 { val, next };
}
template <typename ID, typename T>
inline context<ID, T> make_context(T& val)
{
return { 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 { 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

View File

@@ -0,0 +1,102 @@
/*=============================================================================
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_SUPPORT_NO_CASE_SEPT_24_2014_1125PM)
#define BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
namespace boost { namespace spirit { namespace x3
{
struct no_case_tag {};
template <typename Encoding>
struct case_compare
{
template < template <typename> class basic_charset>
typename Encoding::char_type
in_set( typename Encoding::char_type const ch
, basic_charset<typename Encoding::char_type> const &set)
{
return set.test(ch);
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
{
return lc - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
};
template <typename Encoding>
struct no_case_compare
{
template < template <typename> class basic_charset>
typename Encoding::char_type
in_set( typename Encoding::char_type const ch
, basic_charset<typename Encoding::char_type> const &set)
{
return set.test(ch)
|| set.test(Encoding::islower(ch) ? Encoding::toupper(ch) : Encoding::tolower(ch));
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
{
return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
alpha_tag get_char_class_tag(lower_tag ) const
{
return {};
}
alpha_tag get_char_class_tag(upper_tag ) const
{
return {};
}
};
template <typename Encoding>
case_compare<Encoding> get_case_compare_impl(unused_type const&)
{
return {};
}
template <typename Encoding>
no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
{
return {};
}
template <typename Encoding, typename Context>
inline decltype(auto) get_case_compare(Context const& context)
{
return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
}
auto const no_case_compare_ = no_case_tag{};
}}}
#endif

View File

@@ -0,0 +1,494 @@
/*=============================================================================
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
#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/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>
#include <iterator> // for std::iterator_traits
#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;
template <int Digits, unsigned Radix>
struct digits2_to_n;
// 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 <int Digits> struct digits2_to_n<Digits, Radix> \
{ \
BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
(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
template <typename T, unsigned Radix>
struct digits_traits : digits2_to_n<std::numeric_limits<T>::digits, Radix>
{
static_assert(std::numeric_limits<T>::radix == 2, "");
};
template <typename T>
struct digits_traits<T, 10>
{
static int constexpr value = std::numeric_limits<T>::digits10;
};
///////////////////////////////////////////////////////////////////////////
//
// 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
T const max = (std::numeric_limits<T>::max)();
T const val = max / Radix;
if (n > val)
return false;
T tmp = n * Radix;
// Ensure n += digit will not overflow
const int digit = radix_traits<Radix>::digit(ch);
if (tmp > max - digit)
return false;
n = tmp + 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
T const min = (std::numeric_limits<T>::min)();
T const val = min / T(Radix);
if (n < val)
return false;
T tmp = n * Radix;
// Ensure n -= digit will not underflow
int const digit = radix_traits<Radix>::digit(ch);
if (tmp < min + digit)
return false;
n = tmp - 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_)
{
std::size_t constexpr
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
std::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
std::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
}}}}
#endif

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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
#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, 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

View File

@@ -0,0 +1,240 @@
/*=============================================================================
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_EXTRACT_REAL_APRIL_18_2006_0901AM)
#define BOOST_SPIRIT_X3_EXTRACT_REAL_APRIL_18_2006_0901AM
#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;
}
}}}}
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));
BOOST_ASSERT(frac_digits >= 0);
}
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);
}
// 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

View File

@@ -0,0 +1,112 @@
/*=============================================================================
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
#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

View File

@@ -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_SIGN_MAR_11_2009_0734PM)
#define BOOST_SPIRIT_X3_SIGN_MAR_11_2009_0734PM
#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;
}
template<typename T>
inline T (changesign)(T x)
{
return (boost::math::changesign)(x);
}
}}}
#endif

View File

@@ -0,0 +1,78 @@
/*=============================================================================
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
#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_>
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

View File

@@ -0,0 +1,95 @@
/*=============================================================================
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
#include <boost/mpl/identity.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/eval_if.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/is_range.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/optional_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 {};
struct range_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_optional<T>>::type>
: mpl::identity<optional_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<traits::is_range<T>>::type>
: mpl::identity<range_attribute> {};
template <typename T>
struct attribute_category< T
, typename enable_if<
mpl::and_<
traits::is_container<T>
, mpl::not_<fusion::traits::is_sequence<T> >
, mpl::not_<traits::is_range<T> >
> >::type >
: mpl::identity<container_attribute> {};
}}}}
#endif

View File

@@ -0,0 +1,55 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,26 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,356 @@
/*=============================================================================
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
#include <boost/fusion/support/category_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/fusion/include/deque.hpp>
#include <boost/tti/has_type.hpp>
#include <boost/mpl/identity.hpp>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains some container utils for stl containers.
///////////////////////////////////////////////////////////////////////////
namespace detail
{
BOOST_TTI_HAS_TYPE(value_type)
BOOST_TTI_HAS_TYPE(iterator)
BOOST_TTI_HAS_TYPE(size_type)
BOOST_TTI_HAS_TYPE(reference)
BOOST_TTI_HAS_TYPE(key_type)
}
template <typename T>
using is_container = mpl::bool_<
detail::has_type_value_type<T>::value &&
detail::has_type_iterator<T>::value &&
detail::has_type_size_type<T>::value &&
detail::has_type_reference<T>::value>;
template <typename T>
using is_associative = mpl::bool_<
detail::has_type_key_type<T>::value>;
template<typename T, typename Enable = void>
struct is_reservable : mpl::false_ {};
template<typename T>
struct is_reservable<T, decltype(std::declval<T&>().reserve(0))>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
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(), static_cast<T&&>(val));
return true;
}
};
template <typename Container, typename T>
inline bool push_back(Container& c, T&& val)
{
return push_back_container<Container>::call(c, static_cast<T&&>(val));
}
template <typename Container>
inline bool push_back(Container&, unused_type)
{
return true;
}
template <typename T>
inline bool push_back(unused_type, T&&)
{
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
{
private:
template <typename Iterator>
static void reserve(Container& /* c */, Iterator /* first */, Iterator /* last */, mpl::false_)
{
// Not all containers have "reserve"
}
template <typename Iterator>
static void reserve(Container& c, Iterator first, Iterator last, mpl::true_)
{
c.reserve(c.size() + std::distance(first, last));
}
template <typename Iterator>
static void insert(Container& c, Iterator first, Iterator last, mpl::false_)
{
c.insert(c.end(), first, last);
}
template <typename Iterator>
static void insert(Container& c, Iterator first, Iterator last, mpl::true_)
{
c.insert(first, last);
}
public:
template <typename Iterator>
static bool call(Container& c, Iterator first, Iterator last)
{
reserve(c, first, last, is_reservable<Container>{});
insert(c, first, last, is_associative<Container>{});
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 std::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

View File

@@ -0,0 +1,27 @@
/*=============================================================================
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
#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

View File

@@ -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_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
#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

View File

@@ -0,0 +1,33 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,27 @@
/*=============================================================================
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_RANGE_DEC_06_2017_1900PM)
#define BOOST_SPIRIT_X3_IS_RANGE_DEC_06_2017_1900PM
#include <boost/range/iterator_range.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename T, typename Enable = void>
struct is_range
: mpl::false_
{};
template <typename T>
struct is_range<boost::iterator_range<T>>
: mpl::true_
{};
}}}}
#endif

View File

@@ -0,0 +1,160 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,41 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,227 @@
/*=============================================================================
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
#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/move.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <utility>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Source, typename Dest>
inline void move_to(Source&& src, Dest& dest);
template <typename T>
inline void move_to(T& src, T& dest);
template <typename T>
inline void move_to(T const& src, T& dest);
template <typename T>
inline void move_to(T&& src, T& dest);
template <typename Iterator, typename Dest>
inline void move_to(Iterator first, Iterator last, 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>
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::forward<Source>(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::forward<Source>(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(std::forward<Source>(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 Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, optional_attribute)
{
dest = std::move(src);
}
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, typename Dest>
inline typename enable_if<
is_size_one_sequence<Dest>
>::type
move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)
{
traits::move_to(first, last, fusion::front(dest));
}
template <typename Iterator>
inline void
move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_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 (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
template <typename T>
inline void move_to(T const& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
template <typename T>
inline void move_to(T&& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(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

View File

@@ -0,0 +1,119 @@
/*=============================================================================
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
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <limits>
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::bool_<std::numeric_limits<T>::is_bounded> {};
}}}}
#endif

View File

@@ -0,0 +1,74 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,146 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,75 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,287 @@
/*=============================================================================
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
#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

View File

@@ -0,0 +1,29 @@
/*=============================================================================
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
#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;
}}}}
#endif

View File

@@ -0,0 +1,57 @@
/*=============================================================================
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
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/is_view.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>
>
{};
template <typename View>
struct is_size_one_view
: mpl::and_<
fusion::traits::is_view<View>
, has_size<View, 1>
>
{};
}}}}
#endif

View File

@@ -0,0 +1,24 @@
/*=============================================================================
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
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename T, typename Enable = void>
struct value_initialize
{
static T call()
{
return {};
}
};
}}}}
#endif

View File

@@ -0,0 +1,51 @@
/*=============================================================================
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
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/mpl/find.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<types, 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

View File

@@ -0,0 +1,51 @@
/*=============================================================================
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
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/mpl/find.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<types, 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

View File

@@ -0,0 +1,84 @@
/*=============================================================================
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
#include <iosfwd>
#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>
unused_type get(ID) const
{
return {};
}
};
auto 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

View File

@@ -0,0 +1,51 @@
/*=============================================================================
Copyright (c) 2001-2015 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__ANNOTATE_ON_SUCCESS_HPP)
#define BOOST_SPIRIT_X3__ANNOTATE_ON_SUCCESS_HPP
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/utility/error_reporting.hpp>
#include <boost/spirit/home/x3/support/utility/lambda_visitor.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// The on_success handler tags the AST with the iterator position
// for error handling.
//
// The on_success handler also ties the AST to a vector of iterator
// positions for the purpose of subsequent semantic error handling
// when the program is being compiled. See x3::position_cache in
// x3/support/ast.
//
// We'll ask the X3's error_handler utility to do these.
///////////////////////////////////////////////////////////////////////////
struct annotate_on_success
{
template <typename Iterator, typename Context, typename... Types>
inline void on_success(Iterator const& first, Iterator const& last
, variant<Types...>& ast, Context const& context)
{
ast.apply_visitor(x3::make_lambda_visitor<void>([&](auto& node)
{
this->on_success(first, last, node, context);
}));
}
template <typename T, typename Iterator, typename Context>
inline void on_success(Iterator const& first, Iterator const& last
, T& ast, Context const& context)
{
auto& error_handler = get<error_handler_tag>(context).get();
error_handler.tag(ast, first, last);
}
};
}}}
#endif

View File

@@ -0,0 +1,242 @@
/*=============================================================================
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
#ifndef BOOST_SPIRIT_X3_NO_FILESYSTEM
#include <boost/filesystem/path.hpp>
#endif
#include <boost/locale/encoding_utf.hpp>
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include <ostream>
// Clang-style error handling utilities
namespace boost { namespace spirit { namespace x3
{
// tag used to get our error handler from the context
struct error_handler_tag;
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);
}
boost::iterator_range<Iterator> position_of(position_tagged pos) const
{
return pos_cache.position_of(pos);
}
position_cache<std::vector<Iterator>> const& get_position_cache() const
{
return pos_cache;
}
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
{
if (file != "")
{
#ifdef BOOST_SPIRIT_X3_NO_FILESYSTEM
err_out << "In file " << file << ", ";
#else
namespace fs = boost::filesystem;
err_out << "In file " << fs::path(file).generic_string() << ", ";
#endif
}
else
{
err_out << "In ";
}
err_out << "line " << line << ':' << std::endl;
}
template <typename Iterator>
void error_handler<Iterator>::print_line(Iterator start, Iterator last) const
{
auto end = start;
while (end != last)
{
auto c = *end;
if (c == '\r' || c == '\n')
break;
else
++end;
}
typedef typename std::iterator_traits<Iterator>::value_type char_type;
std::basic_string<char_type> line{start, end};
err_out << locale::conv::utf_to_utf<char>(line) << 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
{
std::size_t line { 1 };
typename std::iterator_traits<Iterator>::value_type prev { 0 };
for (Iterator pos = pos_cache.first(); pos != i; ++pos) {
auto c = *pos;
switch (c) {
case '\n':
if (prev != '\r') ++line;
break;
case '\r':
++line;
break;
default:
break;
}
prev = c;
}
return line;
}
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;
print_line(start, 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;
print_line(start, last);
print_indicator(start, err_first, ' ');
print_indicator(start, err_last, '~');
err_out << " <<-- Here" << std::endl;
}
}}}
#endif

View File

@@ -0,0 +1,35 @@
/*//////////////////////////////////////////////////////////////////////////////
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
#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<
decltype(std::declval<F>()(std::declval<A>()...))>::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

View File

@@ -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

View File

@@ -0,0 +1,26 @@
/*=============================================================================
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
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

View File

@@ -0,0 +1,269 @@
/*=============================================================================
Copyright (c) 2001-2015 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_TEST_UTILITIES)
#define BOOST_SPIRIT_X3_TEST_UTILITIES
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
namespace boost { namespace spirit { namespace x3 { namespace testing
{
namespace fs = boost::filesystem;
////////////////////////////////////////////////////////////////////////////
// compare
//
// Compares the contents of in with the template tem. The template
// may include embedded regular expressions marked up within re_prefix
// and re_suffix tags. For example, given the default RE markup, this
// template <%[0-9]+%> will match any integer in in. 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.
////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct compare_result
{
compare_result(
Iterator pos
, bool full_match
) : pos(pos), full_match(full_match) {}
Iterator pos;
bool full_match;
};
template <typename Range>
compare_result<typename Range::const_iterator>
compare(
Range const& in
, Range const& tem
, char const* re_prefix = "<%"
, char const* re_suffix = "%>"
);
////////////////////////////////////////////////////////////////////////////
// compare
//
// 1) Call f, given the contents of input_path loaded in a string.
// The result of calling f is the output string.
// 2) Compare the result of calling f with expected template
// file (expect_path) using the low-level compare utility
// abive
////////////////////////////////////////////////////////////////////////////
template <typename F>
bool compare(
fs::path input_path, fs::path expect_path
, F f
, char const* re_prefix = "<%"
, char const* re_suffix = "%>"
);
////////////////////////////////////////////////////////////////////////////
// for_each_file
//
// For each *.input and *.expect file in a given directory,
// call the function f, passing in the *.input and *.expect paths.
////////////////////////////////////////////////////////////////////////////
template <typename F>
int for_each_file(fs::path p, F f);
////////////////////////////////////////////////////////////////////////////
// load_file
//
// Load file into a string.
////////////////////////////////////////////////////////////////////////////
std::string load(fs::path p);
////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline bool is_regex(
Iterator& first
, Iterator last
, std::string& re
, char const* re_prefix
, char const* re_suffix
)
{
boost::regex e(re_prefix + std::string("(.*?)") + re_suffix);
boost::match_results<Iterator> what;
if (boost::regex_search(
first, last, what, e
, boost::match_default | boost::match_continuous))
{
re = what[1].str();
first = what[0].second;
return true;
}
return false;
}
template <typename Range>
inline compare_result<typename Range::const_iterator>
compare(
Range const& in
, Range const& tem
, char const* re_prefix
, char const* re_suffix
)
{
typedef typename Range::const_iterator iter_t;
typedef compare_result<iter_t> compare_result_t;
iter_t in_first = in.begin();
iter_t in_last = in.end();
iter_t tem_first = tem.begin();
iter_t tem_last = tem.end();
std::string re;
while (in_first != in_last && tem_first != tem_last)
{
if (is_regex(tem_first, tem_last, re, re_prefix, re_suffix))
{
boost::match_results<iter_t> what;
boost::regex e(re);
if (!boost::regex_search(
in_first, in_last, what, e
, boost::match_default | boost::match_continuous))
{
// RE mismatch: exit now.
return compare_result_t(in_first, false);
}
else
{
// RE match: gobble the matching string.
in_first = what[0].second;
}
}
else
{
// Char by char comparison. Exit if we have a mismatch.
if (*in_first++ != *tem_first++)
return compare_result_t(in_first, false);
}
}
// Ignore trailing spaces in template
bool has_trailing_nonspaces = false;
while (tem_first != tem_last)
{
if (!std::isspace(*tem_first++))
{
has_trailing_nonspaces = true;
break;
}
}
while (in_first != in_last)
{
if (!std::isspace(*in_first++))
{
has_trailing_nonspaces = true;
break;
}
}
// return a full match only if the template is fully matched and if there
// are no more characters to match in the source
return compare_result_t(in_first, !has_trailing_nonspaces);
}
template <typename F>
inline int for_each_file(fs::path p, F f)
{
try
{
if (fs::exists(p) && fs::is_directory(p))
{
for (auto i = fs::directory_iterator(p); i != fs::directory_iterator(); ++i)
{
auto ext = fs::extension(i->path());
if (ext == ".input")
{
auto input_path = i->path();
auto expect_path = input_path;
expect_path.replace_extension(".expect");
f(input_path, expect_path);
}
}
}
else
{
std::cerr << "Directory: " << fs::absolute(p) << " does not exist." << std::endl;
return 1;
}
}
catch (const fs::filesystem_error& ex)
{
std::cerr << ex.what() << '\n';
return 1;
}
return 0;
}
inline std::string load(fs::path p)
{
boost::filesystem::ifstream file(p);
if (!file)
return "";
std::string contents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
return contents;
}
template <typename F>
inline bool compare(
fs::path input_path, fs::path expect_path
, F f
, char const* re_prefix
, char const* re_suffix
)
{
std::string output = f(load(input_path), input_path);
std::string expected = load(expect_path);
auto result = compare(output, expected, re_prefix, re_suffix);
if (!result.full_match)
{
std::cout << "=============================================" << std::endl;
std::cout << "==== Mismatch Found:" << std::endl;
int line = 1;
int col = 1;
for (auto i = output.begin(); i != result.pos; ++i)
{
if (*i == '\n')
{
line++;
col = 0;
}
++col;
}
std::cerr
<< "==== File: " << expect_path
<< ", Line: " << line
<< ", Column: " << col
<< std::endl;
std::cerr << "=============================================" << std::endl;
// Print output
std::cerr << output;
std::cerr << "=============================================" << std::endl;
std::cerr << "==== End" << std::endl;
std::cerr << "=============================================" << std::endl;
return false;
}
return true;
}
}}}}
#endif

View File

@@ -0,0 +1,25 @@
/*//////////////////////////////////////////////////////////////////////////////
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
#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

View File

@@ -0,0 +1,105 @@
/*=============================================================================
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
#include <boost/cstdint.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;
for (Char ch : str)
{
*utf8_iter++ = (UChar)ch;
}
return result;
}
// Assume wchar_t content is UTF-16 on Windows and UCS-4 on Unix
#if defined(_WIN32) || defined(__CYGWIN__)
inline utf8_string to_utf8(wchar_t value)
{
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);
u16_to_u32_iterator<wchar_t const*, ucs4_char> ucs4_iter(&value);
*utf8_iter++ = *ucs4_iter;
return result;
}
inline utf8_string to_utf8(wchar_t const* str)
{
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);
u16_to_u32_iterator<wchar_t const*, ucs4_char> ucs4_iter(str);
for (ucs4_char c; (c = *ucs4_iter) != ucs4_char(); ++ucs4_iter) {
*utf8_iter++ = c;
}
return result;
}
template <typename Traits, typename Allocator>
inline utf8_string
to_utf8(std::basic_string<wchar_t, Traits, Allocator> const& str)
{
return to_utf8(str.c_str());
}
#endif
}}}
#endif