Added thirdparty: boost library

This commit is contained in:
Viacheslav Demydiuk
2024-01-06 19:55:56 +02:00
parent bf49f439e1
commit bccd1e7051
15683 changed files with 3239840 additions and 0 deletions
+517
View File
@@ -0,0 +1,517 @@
/*=============================================================================
Copyright (c) 2001-2011 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_QI_NUMERIC_DETAIL_NUMERIC_UTILS_HPP
#define BOOST_SPIRIT_QI_NUMERIC_DETAIL_NUMERIC_UTILS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/numeric_traits.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/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <iterator> // for std::iterator_traits
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
#endif
namespace boost { namespace spirit { namespace qi { 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_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_LOG2))); \
}; \
/***/
#define BOOST_PP_LOCAL_LIMITS (2, 36)
#include BOOST_PP_LOCAL_ITERATE()
#undef BOOST_SPIRIT_LOG2
template <typename T, unsigned Radix>
struct digits_traits : digits2_to_n<std::numeric_limits<T>::digits, Radix>
{
BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix == 2);
};
template <typename T>
struct digits_traits<T, 10>
{
static int const 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)
{
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 spirit::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, bool AlwaysCheckOverflow>
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 const overflow_free = digits_traits<T, Radix>::value - 1;
if (!AlwaysCheckOverflow && (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)) \
{ \
break; \
} \
if (!extractor::call(ch, count, val)) \
{ \
if (IgnoreOverflowDigits) \
{ \
first = it; \
} \
traits::assign_to(val, attr); \
return IgnoreOverflowDigits; \
} \
++it; \
++count; \
/**/
template <
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename Accumulator = positive_accumulator<Radix>
, bool Accumulate = false
, bool IgnoreOverflowDigits = 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, Accumulate> 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' && (MaxDigits < 0 || leading_zeros < static_cast< std::size_t >(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::assign_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)) \
{ \
traits::assign_to(val, attr); \
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, Accumulate> 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;
traits::assign_to(0, attr);
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::assign_to(val, attr);
first = it;
return true;
}
// count = 0; $$$ verify: I think this is wrong $$$
++it;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
traits::assign_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
}}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
+350
View File
@@ -0,0 +1,350 @@
/*=============================================================================
Copyright (c) 2001-2019 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_QI_NUMERIC_DETAIL_REAL_IMPL_HPP
#define BOOST_SPIRIT_QI_NUMERIC_DETAIL_REAL_IMPL_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <cmath>
#include <boost/limits.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/detail/pow10.hpp>
#include <boost/integer.hpp>
#include <boost/assert.hpp>
#include <boost/core/cmath.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 traits
{
using spirit::traits::pow10;
namespace detail
{
template <typename T, typename AccT>
void compensate_roundoff(T& n, AccT acc_n, mpl::true_)
{
// at the lowest extremes, we compensate for floating point
// roundoff errors by doing imprecise computation using T
int const comp = 10;
n = T((acc_n / comp) * comp);
n += T(acc_n % comp);
}
template <typename T, typename AccT>
void compensate_roundoff(T& n, AccT acc_n, mpl::false_)
{
// no need to compensate
n = acc_n;
}
template <typename T, typename AccT>
void compensate_roundoff(T& n, AccT acc_n)
{
compensate_roundoff(n, acc_n, is_integral<AccT>());
}
}
template <typename T, typename AccT>
inline bool
scale(int exp, T& n, AccT acc_n)
{
if (exp >= 0)
{
int const max_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 = acc_n * pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
{
int const min_exp = std::numeric_limits<T>::min_exponent10;
detail::compensate_roundoff(n, acc_n);
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 = T(acc_n) / pow10<T>(-exp);
}
}
return true;
}
inline bool
scale(int /*exp*/, unused_type /*n*/, unused_type /*acc_n*/)
{
// no-op for unused_type
return true;
}
template <typename T, typename AccT>
inline bool
scale(int exp, int frac, T& n, AccT acc_n)
{
return scale(exp - frac, n, acc_n);
}
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 ? (core::copysign)(n, -1.f) : n;
}
inline double
negate(bool neg, double n)
{
return neg ? (core::copysign)(n, -1.) : n;
}
inline long double
negate(bool neg, long double n)
{
return neg ? (core::copysign)(n, static_cast<long double>(-1)) : n;
}
template <typename T>
inline T
negate(bool neg, T const& n)
{
return neg ? -n : n;
}
inline unused_type
negate(bool /*neg*/, unused_type n)
{
// no-op for unused_type
return n;
}
template <typename T>
struct real_accumulator : mpl::identity<T> {};
template <>
struct real_accumulator<float>
: mpl::identity<uint_t<(sizeof(float)*CHAR_BIT)>::least> {};
template <>
struct real_accumulator<double>
: mpl::identity<uint_t<(sizeof(double)*CHAR_BIT)>::least> {};
}}}
namespace boost { namespace spirit { namespace qi { namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(version)
template <typename T, typename RealPolicies>
struct real_impl
{
template <typename Iterator>
static std::size_t
ignore_excess_digits(Iterator& /* first */, Iterator const& /* last */, mpl::false_)
{
return 0;
}
template <typename Iterator>
static std::size_t
ignore_excess_digits(Iterator& first, Iterator const& last, mpl::true_)
{
return RealPolicies::ignore_excess_digits(first, last);
}
template <typename Iterator>
static std::size_t
ignore_excess_digits(Iterator& first, Iterator const& last)
{
typedef mpl::bool_<has_version<RealPolicies>::value> has_version;
return ignore_excess_digits(first, last, has_version());
}
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;
typename traits::real_accumulator<T>::type acc_n = 0;
bool got_a_number = p.parse_n(first, last, acc_n);
int excess_n = 0;
// 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::assign_to(traits::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;
}
}
else
{
// We got a number and we still see digits. This happens if acc_n (an integer)
// exceeds the integer's capacity. Collect the excess digits.
excess_n = static_cast<int>(ignore_excess_digits(first, last));
}
bool e_hit = false;
Iterator e_pos;
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.
if (excess_n != 0)
{
// We skip the fractions if we already exceeded our digits capacity
ignore_excess_digits(first, last);
}
else if (p.parse_frac_n(first, last, acc_n, frac_digits))
{
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_pos = first;
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_pos = first;
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.
int exp = 0;
if (p.parse_exp_n(first, last, exp))
{
// Got the exponent value. Scale the number by
// exp + excess_n - frac_digits.
if (!traits::scale(exp + excess_n, frac_digits, n, acc_n))
return false;
}
else
{
// 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.
bool r = traits::scale(-frac_digits, n, acc_n);
BOOST_VERIFY(r);
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
bool r = traits::scale(-frac_digits, n, acc_n);
BOOST_VERIFY(r);
}
else
{
if (excess_n)
{
if (!traits::scale(excess_n, n, acc_n))
return false;
}
else
{
n = static_cast<T>(acc_n);
}
}
// If we got a negative sign, negate the number
traits::assign_to(traits::negate(neg, n), attr);
// Success!!!
return true;
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
}}}}
#endif