Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 49 additions & 29 deletions include/boost/spirit/home/x3/numeric/int.hpp
Original file line number Diff line number Diff line change
@@ -1,62 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka

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_INT_APR_17_2006_0830AM)
#ifndef BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM
#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM

#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>

#include <iterator>
#include <cstdint>

namespace boost { namespace spirit { namespace x3
namespace boost::spirit::x3
{
///////////////////////////////////////////////////////////////////////////
template <
typename T
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1>
typename T,
unsigned Radix = 10,
unsigned MinDigits = 1,
int MaxDigits = -1
>
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits>>
{
// check template parameter 'Radix' for validity
static_assert(
(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
"Error Unsupported Radix");
"Unsupported Radix"
);

typedef T attribute_type;
static bool const has_attribute = true;
using attribute_type = T;
static constexpr bool has_attribute = true;

template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Context, typename Attribute>
[[nodiscard]] constexpr bool parse(
It& first, Se const& last,
Context const& context, unused_type, Attribute& attr
) const noexcept(
noexcept(x3::skip_over(first, last, context)) &&
noexcept(extract_int<T, Radix, MinDigits, MaxDigits>::call(first, last, attr))
)
{
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
x3::skip_over(first, last, context);
return extract::call(first, last, attr);
return extract_int<T, Radix, MinDigits, MaxDigits>::call(first, last, attr);
}
};

#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name) \
typedef int_parser<int_type> name##type; \
constexpr name##type name = {}; \
/***/
inline namespace cpos
{
using short_type = int_parser<short>;
inline constexpr short_type short_{};

using int_type = int_parser<int>;
inline constexpr int_type int_{};

using long_type = int_parser<long>;
inline constexpr long_type long_{};

using long_long_type = int_parser<long long>;
inline constexpr long_long_type long_long{};


using int8_type = int_parser<std::int8_t>;
inline constexpr int8_type int8{};

using int16_type = int_parser<std::int16_t>;
inline constexpr int16_type int16{};

BOOST_SPIRIT_X3_INT_PARSER(long, long_)
BOOST_SPIRIT_X3_INT_PARSER(short, short_)
BOOST_SPIRIT_X3_INT_PARSER(int, int_)
BOOST_SPIRIT_X3_INT_PARSER(long long, long_long)
using int32_type = int_parser<std::int32_t>;
inline constexpr int32_type int32{};

BOOST_SPIRIT_X3_INT_PARSER(int8_t, int8)
BOOST_SPIRIT_X3_INT_PARSER(int16_t, int16)
BOOST_SPIRIT_X3_INT_PARSER(int32_t, int32)
BOOST_SPIRIT_X3_INT_PARSER(int64_t, int64)
using int64_type = int_parser<std::int64_t>;
inline constexpr int64_type int64{};

#undef BOOST_SPIRIT_X3_INT_PARSER
} // cpos

}}}
} // boost::spirit::x3

#endif
83 changes: 55 additions & 28 deletions include/boost/spirit/home/x3/numeric/real.hpp
Original file line number Diff line number Diff line change
@@ -1,65 +1,92 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka

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_REAL_APRIL_18_2006_0850AM)
#ifndef BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM
#define BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM

#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/numeric/real_policies.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_real.hpp>

namespace boost { namespace spirit { namespace x3
#include <iterator>
#include <type_traits>
#include <utility>

namespace boost::spirit::x3
{
template <typename T, typename RealPolicies = real_policies<T> >
struct real_parser : parser<real_parser<T, RealPolicies> >
template <typename T, typename RealPolicies = real_policies<T>>
struct real_parser : parser<real_parser<T, RealPolicies>>
{
typedef T attribute_type;
static bool const has_attribute = true;
using attribute_type = T;
using policies_type = RealPolicies;

static constexpr bool has_attribute = true;

constexpr real_parser()
: policies() {}
constexpr real_parser() = default;

constexpr real_parser(RealPolicies const& policies)
: policies(policies) {}
template <typename RealPoliciesT>
requires
(!std::is_same_v<std::remove_cvref_t<RealPoliciesT>, real_parser>) &&
std::is_constructible_v<RealPolicies, RealPoliciesT>
constexpr real_parser(RealPoliciesT&& policies)
noexcept(std::is_nothrow_constructible_v<RealPolicies, RealPoliciesT>)
: policies_(std::forward<RealPoliciesT>(policies))
{}

template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, T& attr_) const
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Context>
[[nodiscard]] constexpr bool
parse(
It& first, Se const& last,
Context const& context, unused_type, T& attr_
) const noexcept(
noexcept(x3::skip_over(first, last, context)) &&
noexcept(extract_real<T, RealPolicies>::parse(first, last, attr_, policies_))
)
{
x3::skip_over(first, last, context);
return extract_real<T, RealPolicies>::parse(first, last, attr_, policies);
return extract_real<T, RealPolicies>::parse(first, last, attr_, policies_);
}

template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr_param) const
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Context, typename Attribute>
[[nodiscard]] constexpr bool
parse(It& first, Se const& last,
Context const& context, unused_type, Attribute& attr_param
) const noexcept(
std::is_nothrow_default_constructible_v<T> &&
noexcept(this->parse(first, last, context, unused, std::declval<T&>())) &&
noexcept(traits::move_to(std::declval<T&&>(), attr_param))
)
{
// this case is called when Attribute is not T
T attr_;
if (parse(first, last, context, unused, attr_))
if (this->parse(first, last, context, unused, attr_))
{
traits::move_to(attr_, attr_param);
traits::move_to(std::move(attr_), attr_param);
return true;
}
return false;
}

RealPolicies policies;
private:
RealPolicies policies_{};
};

typedef real_parser<float> float_type;
constexpr float_type float_ = {};

typedef real_parser<double> double_type;
constexpr double_type double_ = {};
inline namespace cpos
{
using float_type = real_parser<float>;
inline constexpr float_type float_{};

typedef real_parser<long double> long_double_type;
constexpr long_double_type long_double = {};
using double_type = real_parser<double>;
inline constexpr double_type double_{};

}}}
using long_double_type = real_parser<long double>;
inline constexpr long_double_type long_double{};
} // cpos
} // boost::spirit::x3

#endif
Loading