update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -7,7 +7,7 @@
#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/range/iterator_range_core.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/core/enable_if.hpp>

View File

@@ -18,22 +18,18 @@ namespace boost { namespace spirit { namespace x3
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)
template <typename Char, typename CharSet>
bool in_set(Char ch, CharSet const& set)
{
return set.test(ch);
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
template <typename Char>
int32_t operator()(Char lc, Char rc) const
{
return lc - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
@@ -44,20 +40,24 @@ namespace boost { namespace spirit { namespace x3
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)
template <typename Char, typename CharSet>
bool in_set(Char ch_, CharSet const& set)
{
using char_type = typename Encoding::classify_type;
auto ch = char_type(ch_);
return set.test(ch)
|| set.test(Encoding::islower(ch) ? Encoding::toupper(ch) : Encoding::tolower(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
template <typename Char>
int32_t operator()(Char lc_, Char const rc_) const
{
return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
using char_type = typename Encoding::classify_type;
auto lc = char_type(lc_);
auto rc = char_type(rc_);
return Encoding::islower(rc)
? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
}
template <typename CharClassTag>
@@ -95,6 +95,7 @@ namespace boost { namespace spirit { namespace x3
{
return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
}
auto const no_case_compare_ = no_case_tag{};
}}}

View File

@@ -112,19 +112,17 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
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));
return (ch >= '0' && ch <= (Radix > 10 ? '9' : static_cast<Char>('0' + Radix -1)))
|| (Radix > 10 && ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|| (Radix > 10 && 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;
return (Radix <= 10 || (ch >= '0' && ch <= '9'))
? ch - '0'
: char_encoding::ascii::tolower(ch) - 'a' + 10;
}
};
@@ -300,6 +298,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4459) // declaration hides global declaration
#endif
template <typename Iterator, typename Attribute>
inline static bool
@@ -398,6 +397,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4459) // declaration hides global declaration
#endif
template <typename Iterator, typename Attribute>
inline static bool

View File

@@ -14,7 +14,6 @@
#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>
@@ -29,65 +28,79 @@ namespace boost { namespace spirit { namespace x3 { namespace extension
using x3::traits::pow10;
template <typename T>
inline void
inline bool
scale(int exp, T& n)
{
constexpr auto max_exp = std::numeric_limits<T>::max_exponent10;
constexpr auto min_exp = std::numeric_limits<T>::min_exponent10;
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);
// return false if exp exceeds the max_exp
// do this check only for primitive types!
if (is_floating_point<T>() && exp > max_exp)
return false;
n *= pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
if (exp < min_exp)
{
n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-min_exp);
// return false if exp still exceeds the min_exp
// do this check only for primitive types!
exp += -min_exp;
if (is_floating_point<T>() && exp < min_exp)
return false;
n /= pow10<T>(-exp);
}
else
{
n /= pow10<T>(-exp);
}
}
return true;
}
inline void
inline bool
scale(int /*exp*/, unused_type /*n*/)
{
// no-op for unused_type
return true;
}
template <typename T>
inline void
inline bool
scale(int exp, int frac, T& n)
{
scale(exp - frac, n);
return scale(exp - frac, n);
}
inline void
inline bool
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
return true;
}
inline float
negate(bool neg, float n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysignf)(n, -1.f) : n;
}
inline double
negate(bool neg, double n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysign)(n, -1.) : n;
}
inline long double
negate(bool neg, long double n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysignl)(n, -1.) : n;
}
template <typename T>
@@ -150,6 +163,7 @@ namespace boost { namespace spirit { namespace x3
}
bool e_hit = false;
Iterator e_pos;
int frac_digits = 0;
// Try to parse the dot ('.' decimal point)
@@ -178,6 +192,7 @@ namespace boost { namespace spirit { namespace x3
}
// Now, let's see if we can parse the exponent prefix
e_pos = first;
e_hit = p.parse_exp(first, last);
}
else
@@ -191,6 +206,7 @@ namespace boost { namespace spirit { namespace x3
// If we must expect a dot and we didn't see an exponent
// prefix, return no-match.
e_pos = first;
e_hit = p.parse_exp(first, last);
if (p.expect_dot && !e_hit)
{
@@ -208,19 +224,25 @@ namespace boost { namespace spirit { namespace x3
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
extension::scale(exp, frac_digits, n);
if (!extension::scale(exp, frac_digits, n))
return false;
}
else
{
// Oops, no exponent, return no-match.
first = save;
return false;
// If there is no number, disregard the exponent altogether.
// by resetting 'first' prior to the exponent prefix (e|E)
first = e_pos;
// Scale the number by -frac_digits.
if (!extension::scale(-frac_digits, n))
return false;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
extension::scale(-frac_digits, n);
if (!extension::scale(-frac_digits, n))
return false;
}
// If we got a negative sign, negate the number

View File

@@ -13,6 +13,7 @@
#include <boost/limits.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#include <cfloat>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)

View File

@@ -1,30 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SIGN_MAR_11_2009_0734PM)
#define BOOST_SPIRIT_X3_SIGN_MAR_11_2009_0734PM
#include <boost/math/special_functions/sign.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename T>
inline bool (signbit)(T x)
{
return (boost::math::signbit)(x) ? true : false;
}
template<typename T>
inline T (changesign)(T x)
{
return (boost::math::changesign)(x);
}
}}}
#endif

View File

@@ -1,6 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustín Bergé
Copyright (c) 2013 Agustin Berge
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@@ -16,8 +16,8 @@
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
// 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).
///////////////////////////////////////////////////////////////////////////
@@ -28,28 +28,27 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Component, typename Context, typename Enable = void>
struct default_attribute_of;
template <typename Component, typename Context>
struct default_attribute_of<Component, 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,
struct default_attribute_of<Component, Context,
typename disable_if_substitution_failure<
typename Component::template attribute<Context>::type>::type>
: Component::template attribute<Context> {};
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
typename enable_if_c<Component::is_pass_through_unary>::type>
: attribute_of<typename Component::subject_type, Context>{};
}
template <typename Component, typename Context, typename Enable>
struct attribute_of : detail::default_attribute_of<Component, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2020 Nikita Kniazev
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_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY
#define BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/type_traits/type_identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename... T>
struct type_sequence
{
using type = type_sequence;
static const int size = sizeof...(T);
template <typename... U>
using append = type_sequence<T..., U...>;
template <typename... U>
using prepend = type_sequence<U..., T...>;
template <typename U>
using extend = typename U::template prepend<T...>;
template <template <typename...> class U>
using transfer_to = U<T...>;
};
template <typename Attribute>
struct types_of_binary_init : type_sequence<Attribute> {};
template <>
struct types_of_binary_init<unused_type> : type_sequence<> {};
template <>
struct types_of_binary_init<unused_type const> : type_sequence<> {};
template <template <typename, typename> class B, typename P, typename C>
struct get_types_of_binary
: types_of_binary_init<typename traits::attribute_of<P, C>::type> {};
template <template <typename, typename> class B, typename L, typename R, typename C>
struct get_types_of_binary<B, B<L, R>, C>
: get_types_of_binary<B, L, C>::template extend<get_types_of_binary<B, R, C>> {};
template <template <typename...> class A, typename T, int = T::size>
struct type_sequence_to_attribute { using type = typename T::template transfer_to<A>; };
template <template <typename...> class A, typename T>
struct type_sequence_to_attribute<A, T, 1> : T::template transfer_to<type_identity> {};
template <template <typename...> class A, typename T>
struct type_sequence_to_attribute<A, T, 0> { using type = unused_type; };
template <template <typename...> class A, template <typename, typename> class B,
typename L, typename R, typename C>
using attribute_of_binary = type_sequence_to_attribute<A,
typename get_types_of_binary<B, B<L, R>, C>::type>;
}}}}
#endif

View File

@@ -12,8 +12,8 @@
#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 <boost/type_traits/make_void.hpp>
#include <vector>
#include <string>
@@ -28,30 +28,27 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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, typename Enabler = void>
struct is_container_impl : mpl::false_ {};
template <typename T>
struct is_container_impl<T, void_t<
typename T::value_type, typename T::iterator,
typename T::size_type, typename T::reference> > : mpl::true_ {};
template <typename T, typename Enabler = void>
struct is_associative_impl : mpl::false_ {};
template <typename T>
struct is_associative_impl<T, void_t<typename T::key_type>>
: mpl::true_ {};
}
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>;
using is_container = typename detail::is_container_impl<T>::type;
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_ {};
using is_associative = typename detail::is_associative_impl<T>::type;
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -158,18 +155,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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_)
{
@@ -186,7 +171,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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;
}

View File

@@ -8,7 +8,7 @@
#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/range/range_fwd.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits

View File

@@ -46,7 +46,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{};
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute_impl : is_same<T, Attribute> {};
struct is_substitute_impl : mpl::false_ {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
@@ -75,16 +75,15 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typename enable_if<
is_variant<Attribute>
>::type>
: mpl::or_<
is_same<T, Attribute>
, variant_has_substitute<Attribute, T>
>
: variant_has_substitute<Attribute, T>
{};
}
template <typename T, typename Attribute, typename Enable /*= void*/>
struct is_substitute
: detail::is_substitute_impl<T, Attribute> {};
: mpl::or_<
is_same<T, Attribute>,
detail::is_substitute_impl<T, Attribute>> {};
// for reference T
template <typename T, typename Attribute, typename Enable>

View File

@@ -12,6 +12,8 @@
#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/assert.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/move.hpp>
@@ -51,37 +53,37 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Source, typename Dest>
inline void
move_to(Source&&, Dest&, unused_attribute) {}
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
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
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)
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);
move_to_plain(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)
move_to(Source& src, Dest& dest, container_attribute)
{
traits::move_to(src.begin(), src.end(), dest);
}
@@ -92,30 +94,30 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
is_same_size_sequence<Dest, Source>,
mpl::not_<is_size_one_sequence<Dest> > >
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
move_to(Source& src, Dest& dest, tuple_attribute)
{
fusion::move(std::forward<Source>(src), dest);
fusion::move(std::move(src), dest);
}
template <typename Source, typename Dest>
inline typename enable_if<
is_size_one_sequence<Dest>
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
move_to(Source& src, Dest& dest, tuple_attribute)
{
traits::move_to(std::forward<Source>(src), fusion::front(dest));
traits::move_to(src, fusion::front(dest));
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
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_)
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.
@@ -129,7 +131,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Source, typename Dest>
inline void
move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::true_)
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.
@@ -138,21 +140,21 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
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(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)
move_to(Source& src, Dest& dest, optional_attribute)
{
dest = std::move(src);
}
@@ -191,29 +193,28 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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());
detail::move_to(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);
BOOST_ASSERT(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);
BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
dest = src;
}
template <typename T>
inline void move_to(T&& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
dest = std::move(src);
}
template <typename Iterator, typename Dest>

View File

@@ -14,6 +14,9 @@
#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>
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/support/char_encoding/unicode.hpp>
#endif
namespace boost { namespace spirit { namespace x3 { namespace traits
{
@@ -67,9 +70,8 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
// for unused_type
static void call(Out& out, unused_type, unused_attribute)
{
out << "unused";
}
@@ -81,6 +83,28 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
out << val;
}
#ifdef BOOST_SPIRIT_X3_UNICODE
static void call(Out& out, char_encoding::unicode::char_type val, plain_attribute)
{
if (val >= 0 && val < 127)
{
if (iscntrl(val))
out << "\\" << std::oct << int(val) << std::dec;
else if (isprint(val))
out << char(val);
else
out << "\\x" << std::hex << int(val) << std::dec;
}
else
out << "\\x" << std::hex << int(val) << std::dec;
}
static void call(Out& out, char val, plain_attribute tag)
{
call(out, static_cast<char_encoding::unicode::char_type>(val), tag);
}
#endif
// for fusion data types
template <typename T_>
static void call(Out& out, T_ const& val, tuple_attribute)

View File

@@ -12,6 +12,7 @@
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cctype>
#include <ios>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
@@ -36,10 +37,17 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
case '\t': o << "\\t"; break;
case '\v': o << "\\v"; break;
default:
if (c >= 0 && c < 127 && iscntrl(c))
if (c >= 0 && c < 127)
{
if (iscntrl(c))
o << "\\" << std::oct << int(c);
else if (isprint(c))
o << char(c);
else
o << "\\x" << std::hex << int(c);
}
else
o << Char(c);
o << "\\x" << std::hex << int(c);
}
}
};

View File

@@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2019 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_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM)
#define BOOST_SPIRIT_X3_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM
#include <utility>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Pseudo attributes are placeholders for parsers that can only know
// its actual attribute at parse time. This trait customization point
// provides a mechanism to convert the trait to the actual trait at
// parse time.
///////////////////////////////////////////////////////////////////////////
template <typename Context, typename Attribute, typename Iterator
, typename Enable = void>
struct pseudo_attribute
{
using attribute_type = Attribute;
using type = Attribute;
static type&& call(Iterator&, Iterator const&, attribute_type&& attribute)
{
return std::forward<type>(attribute);
}
};
}}}}
#endif

View File

@@ -11,128 +11,9 @@
#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
///////////////////////////////////////////////////////////////////////////
@@ -142,8 +23,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
{
@@ -161,9 +40,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
static decltype(auto) call(T const str)
{
return extract_c_string<T>::call(str);
}
@@ -173,9 +50,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
static decltype(auto) call(T& str)
{
return extract_c_string<T>::call(str);
}
@@ -185,9 +60,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
static decltype(auto) call(T const& str)
{
return extract_c_string<T>::call(str);
}
@@ -196,8 +69,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
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)
@@ -207,29 +78,25 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
};
template <typename T>
typename extract_c_string<T*>::char_type const*
get_c_string(T* str)
decltype(auto) 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)
decltype(auto) 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)
decltype(auto) 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)
decltype(auto) get_c_string(String const& str)
{
return extract_c_string<String>::call(str);
}

View File

@@ -1,24 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename T, typename Enable = void>
struct value_initialize
{
static T call()
{
return {};
}
};
}}}}
#endif

View File

@@ -13,22 +13,22 @@
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_find_substitute
{
// Get the type from the variant that can be a substitute for Attribute.
// If none is found, just return Attribute
// Get the type from the Variant that can be a substitute for T.
// If none is found, just return T
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::find<types, T>::type iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
mpl::find_if<types, traits::is_substitute<T, mpl::_1> >,
mpl::identity<iter_1>
>::type
iter;
@@ -36,7 +36,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typedef typename
mpl::eval_if<
is_same<iter, end>,
mpl::identity<Attribute>,
mpl::identity<T>,
mpl::deref<iter>
>::type
type;

View File

@@ -13,22 +13,22 @@
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_has_substitute_impl
{
// Find a type from the variant that can be a substitute for Attribute.
// Find a type from the Variant that can be a substitute for T.
// 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::find<types, T>::type iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
mpl::find_if<types, traits::is_substitute<T, mpl::_1>>,
mpl::identity<iter_1>
>::type
iter;
@@ -36,15 +36,15 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typedef mpl::not_<is_same<iter, end>> type;
};
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_has_substitute
: variant_has_substitute_impl<Variant, Attribute>::type {};
: variant_has_substitute_impl<Variant, T>::type {};
template <typename Attribute>
struct variant_has_substitute<unused_type, Attribute> : mpl::true_ {};
template <typename T>
struct variant_has_substitute<unused_type, T> : mpl::true_ {};
template <typename Attribute>
struct variant_has_substitute<unused_type const, Attribute> : mpl::true_ {};
template <typename T>
struct variant_has_substitute<unused_type const, T> : mpl::true_ {};
}}}}

View File

@@ -10,19 +10,12 @@
#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()
{
}
unused_type() = default;
template <typename T>
unused_type(T const&)
@@ -43,18 +36,6 @@ namespace boost { namespace spirit { namespace x3
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>
@@ -62,23 +43,19 @@ namespace boost { namespace spirit { namespace x3
{
return {};
}
friend std::ostream& operator<<(std::ostream& out, unused_type const&)
{
return out;
}
friend std::istream& operator>>(std::istream& in, unused_type&)
{
return in;
}
};
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;
}
constexpr auto unused = unused_type{};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -11,6 +11,7 @@
#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>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -40,9 +41,16 @@ namespace boost { namespace spirit { namespace x3
template <typename T, typename Iterator, typename Context>
inline void on_success(Iterator const& first, Iterator const& last
, forward_ast<T>& ast, Context const& context)
{
this->on_success(first, last, ast.get(), context);
}
template <typename T, typename Iterator, typename Context>
inline typename disable_if<traits::is_variant<T>>::type on_success(Iterator const& first, Iterator const& last
, T& ast, Context const& context)
{
auto& error_handler = get<error_handler_tag>(context).get();
auto& error_handler = x3::get<error_handler_tag>(context).get();
error_handler.tag(ast, first, last);
}
};

View File

@@ -7,12 +7,8 @@
#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 <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <ostream>
// Clang-style error handling utilities
@@ -68,8 +64,6 @@ namespace boost { namespace spirit { namespace x3
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;
@@ -84,12 +78,7 @@ namespace boost { namespace spirit { namespace x3
{
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
{
@@ -113,7 +102,7 @@ namespace boost { namespace spirit { namespace x3
}
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;
err_out << x3::to_utf8(line) << std::endl;
}
template <typename Iterator>
@@ -132,41 +121,15 @@ namespace boost { namespace spirit { namespace x3
}
}
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)
for (Iterator i = first; i != pos;)
if (*i == '\r' || *i == '\n')
latest = i;
latest = ++i;
else
++i;
return latest;
}
@@ -201,15 +164,10 @@ namespace boost { namespace spirit { namespace x3
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;
@@ -222,15 +180,10 @@ namespace boost { namespace spirit { namespace x3
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, '~');

View File

@@ -8,7 +8,6 @@
#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
{
@@ -16,8 +15,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
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>
struct is_callable_impl<F(A...),
decltype(void(std::declval<F>()(std::declval<A>()...)))>
: mpl::true_
{};
}}}}

View File

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

View File

@@ -1,25 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014 Jamboree
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////*/
#ifndef BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
#define BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename T>
struct unrefcv : remove_cv<typename remove_reference<T>::type> {};
template <typename T>
using unrefcv_t = typename unrefcv<T>::type;
}}}
#endif

View File

@@ -1,5 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2023 Nikita Kniazev
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)
@@ -7,42 +8,62 @@
#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 <boost/config.hpp>
#include <type_traits>
#include <string>
namespace boost { namespace spirit { namespace x3
{
typedef ::boost::uint32_t ucs4_char;
typedef char32_t ucs4_char;
typedef char utf8_char;
typedef std::basic_string<ucs4_char> ucs4_string;
typedef std::basic_string<utf8_char> utf8_string;
namespace detail {
inline void utf8_put_encode(utf8_string& out, ucs4_char x)
{
// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf D90
if (BOOST_UNLIKELY(x > 0x10FFFFul || (0xD7FFul < x && x < 0xE000ul)))
x = 0xFFFDul;
// Table 3-6. UTF-8 Bit Distribution
if (x < 0x80ul) {
out.push_back(static_cast<unsigned char>(x));
}
else if (x < 0x800ul) {
out.push_back(static_cast<unsigned char>(0xC0ul + (x >> 6)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else if (x < 0x10000ul) {
out.push_back(static_cast<unsigned char>(0xE0ul + (x >> 12)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else {
out.push_back(static_cast<unsigned char>(0xF0ul + (x >> 18)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 12) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
}
}
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;
typedef typename std::make_unsigned<Char>::type UChar;
detail::utf8_put_encode(result, static_cast<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;
typedef typename std::make_unsigned<Char>::type UChar;
while (*str)
*utf8_iter++ = (UChar)*str++;
detail::utf8_put_encode(result, static_cast<UChar>(*str++));
return result;
}
@@ -50,46 +71,49 @@ namespace boost { namespace spirit { namespace x3
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;
typedef typename std::make_unsigned<Char>::type UChar;
for (Char ch : str)
{
*utf8_iter++ = (UChar)ch;
}
detail::utf8_put_encode(result, static_cast<UChar>(ch));
return result;
}
// Assume wchar_t content is UTF-16 on Windows and UCS-4 on Unix
#if defined(_WIN32) || defined(__CYGWIN__)
// Assume wchar_t content is UTF-16 on MSVC, or mingw/wineg++ with -fshort-wchar
#if defined(_MSC_VER) || defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2
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;
detail::utf8_put_encode(result, static_cast<std::make_unsigned<wchar_t>::type>(value));
return result;
}
namespace detail {
inline ucs4_char decode_utf16(wchar_t const*& s)
{
typedef std::make_unsigned<wchar_t>::type uwchar_t;
uwchar_t x(*s);
if (x < 0xD800ul || x > 0xDFFFul)
return x;
// expected high-surrogate
if (BOOST_UNLIKELY((x >> 10) != 0b110110ul))
return 0xFFFDul;
uwchar_t y(*++s);
// expected low-surrogate
if (BOOST_UNLIKELY((y >> 10) != 0b110111ul))
return 0xFFFDul;
return ((x & 0x3FFul) << 10) + (y & 0x3FFul) + 0x10000ul;
}
}
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;
}
for (ucs4_char c; (c = detail::decode_utf16(str)) != ucs4_char(); ++str)
detail::utf8_put_encode(result, c);
return result;
}