add boost on mac
This commit is contained in:
@@ -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
|
||||
265
macx64/include/boost/spirit/home/x3/support/ast/variant.hpp
Normal file
265
macx64/include/boost/spirit/home/x3/support/ast/variant.hpp
Normal 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
|
||||
103
macx64/include/boost/spirit/home/x3/support/context.hpp
Normal file
103
macx64/include/boost/spirit/home/x3/support/context.hpp
Normal 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
|
||||
102
macx64/include/boost/spirit/home/x3/support/no_case.hpp
Normal file
102
macx64/include/boost/spirit/home/x3/support/no_case.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
78
macx64/include/boost/spirit/home/x3/support/subcontext.hpp
Normal file
78
macx64/include/boost/spirit/home/x3/support/subcontext.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
227
macx64/include/boost/spirit/home/x3/support/traits/move_to.hpp
Normal file
227
macx64/include/boost/spirit/home/x3/support/traits/move_to.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
84
macx64/include/boost/spirit/home/x3/support/unused.hpp
Normal file
84
macx64/include/boost/spirit/home/x3/support/unused.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
269
macx64/include/boost/spirit/home/x3/support/utility/testing.hpp
Normal file
269
macx64/include/boost/spirit/home/x3/support/utility/testing.hpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
105
macx64/include/boost/spirit/home/x3/support/utility/utf8.hpp
Normal file
105
macx64/include/boost/spirit/home/x3/support/utility/utf8.hpp
Normal 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
|
||||
Reference in New Issue
Block a user