2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-19 04:22:13 +00:00

When there are alternate implementations controlled by __has_include, put each

alternate implementation in its own inline namespace.

Fixes #151.
This commit is contained in:
Zach Laine
2024-03-03 21:53:17 -06:00
parent 947fd7782d
commit 456a81155a
2 changed files with 83 additions and 72 deletions

View File

@@ -18,10 +18,15 @@
#if defined(__cpp_lib_to_chars)
#include <charconv>
#define BOOST_PARSER_HAVE_STD_CHARCONV
#define BOOST_PARSER_NUMERIC_NS std_charconv
#elif __has_include(<boost/charconv.hpp>)
#include <boost/charconv.hpp>
#define BOOST_PARSER_HAVE_BOOST_CHARCONV
#define BOOST_PARSER_NUMERIC_NS boost_charconv
#else
#define BOOST_PARSER_NUMERIC_NS spirit_parsers
#endif
#include <type_traits>
#include <cmath>
@@ -999,85 +1004,87 @@ namespace boost::parser::detail::numeric {
std::remove_pointer_t<unpacked_iter<I, S>>>>,
char>;
template<int MinDigits, int MaxDigits, typename I, typename S>
inline namespace BOOST_PARSER_NUMERIC_NS {
template<int MinDigits, int MaxDigits, typename I, typename S>
#if defined(BOOST_PARSER_HAVE_CHARCONV)
constexpr bool use_charconv_int =
MinDigits == 1 && MaxDigits == -1 &&
common_range<I, S> && unpacks_to_chars<I, S>;
constexpr bool use_charconv_int =
MinDigits == 1 && MaxDigits == -1 &&
common_range<I, S> && unpacks_to_chars<I, S>;
#else
constexpr bool use_charconv_int = false;
constexpr bool use_charconv_int = false;
#endif
template<
bool Signed,
int Radix,
int MinDigits,
int MaxDigits,
typename I,
typename S,
typename T>
bool parse_int(I & first, S last, T & attr)
{
if constexpr (use_charconv_int<MinDigits, MaxDigits, I, S>) {
template<
bool Signed,
int Radix,
int MinDigits,
int MaxDigits,
typename I,
typename S,
typename T>
bool parse_int(I & first, S last, T & attr)
{
if constexpr (use_charconv_int<MinDigits, MaxDigits, I, S>) {
#if defined(BOOST_PARSER_HAVE_CHARCONV)
auto unpacked = text::unpack_iterator_and_sentinel(first, last);
auto unpacked = text::unpack_iterator_and_sentinel(first, last);
#if defined(BOOST_PARSER_HAVE_STD_CHARCONV)
std::from_chars_result const result = std::from_chars(
std::from_chars_result const result = std::from_chars(
#else
charconv::from_chars_result const result = charconv::from_chars(
charconv::from_chars_result const result = charconv::from_chars(
#endif
unpacked.first, unpacked.last, attr, Radix);
if (result.ec == std::errc()) {
first = unpacked.repack(result.ptr);
return true;
unpacked.first, unpacked.last, attr, Radix);
if (result.ec == std::errc()) {
first = unpacked.repack(result.ptr);
return true;
}
return false;
#endif
} else if constexpr (Signed) {
using extract = detail_spirit_x3::
extract_int<T, Radix, MinDigits, MaxDigits>;
return extract::call(first, last, attr);
} else {
using extract = detail_spirit_x3::
extract_uint<T, Radix, MinDigits, MaxDigits>;
return extract::call(first, last, attr);
}
return false;
}
template<typename I, typename S>
#if defined(BOOST_PARSER_HAVE_CHARCONV)
constexpr bool use_charconv_real =
common_range<I, S> && unpacks_to_chars<I, S>;
#else
constexpr bool use_charconv_real = false;
#endif
} else if constexpr (Signed) {
using extract =
detail_spirit_x3::extract_int<T, Radix, MinDigits, MaxDigits>;
return extract::call(first, last, attr);
} else {
using extract =
detail_spirit_x3::extract_uint<T, Radix, MinDigits, MaxDigits>;
return extract::call(first, last, attr);
template<typename I, typename S, typename T>
bool parse_real(I & first, S last, T & attr)
{
if constexpr (use_charconv_real<I, S>) {
#if defined(BOOST_PARSER_HAVE_CHARCONV)
auto unpacked = text::unpack_iterator_and_sentinel(first, last);
#if defined(BOOST_PARSER_HAVE_STD_CHARCONV)
std::from_chars_result const result = std::from_chars(
#else
charconv::from_chars_result const result = charconv::from_chars(
#endif
unpacked.first, unpacked.last, attr);
if (result.ec == std::errc()) {
first = unpacked.repack(result.ptr);
return true;
}
return false;
#endif
} else {
detail_spirit_x3::real_policies<T> policies;
using extract = detail_spirit_x3::
extract_real<T, detail_spirit_x3::real_policies<T>>;
return extract::parse(first, last, attr, policies);
}
}
}
template<typename I, typename S>
#if defined(BOOST_PARSER_HAVE_CHARCONV)
constexpr bool use_charconv_real =
common_range<I, S> && unpacks_to_chars<I, S>;
#else
constexpr bool use_charconv_real = false;
#endif
template<typename I, typename S, typename T>
bool parse_real(I & first, S last, T & attr)
{
if constexpr (use_charconv_real<I, S>) {
#if defined(BOOST_PARSER_HAVE_CHARCONV)
auto unpacked = text::unpack_iterator_and_sentinel(first, last);
#if defined(BOOST_PARSER_HAVE_STD_CHARCONV)
std::from_chars_result const result = std::from_chars(
#else
charconv::from_chars_result const result = charconv::from_chars(
#endif
unpacked.first, unpacked.last, attr);
if (result.ec == std::errc()) {
first = unpacked.repack(result.ptr);
return true;
}
return false;
#endif
} else {
detail_spirit_x3::real_policies<T> policies;
using extract = detail_spirit_x3::
extract_real<T, detail_spirit_x3::real_policies<T>>;
return extract::parse(first, last, attr, policies);
}
}
}
#endif

View File

@@ -10,25 +10,29 @@
#endif
#include <boost/type_index.hpp>
#define BOOST_PARSER_HAVE_BOOST_TYPEINDEX 1
#define BOOST_PARSER_TYPE_NAME_NS boost_type_index
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#else
#include <typeinfo>
#define BOOST_PARSER_HAVE_BOOST_TYPEINDEX 0
#define BOOST_PARSER_TYPE_NAME_NS std_typeinfo
#endif
namespace boost { namespace parser { namespace detail {
template<typename T>
auto type_name()
{
inline namespace BOOST_PARSER_TYPE_NAME_NS {
template<typename T>
auto type_name()
{
#if BOOST_PARSER_HAVE_BOOST_TYPEINDEX
return typeindex::type_id<T>().pretty_name();
return typeindex::type_id<T>().pretty_name();
#else
return typeid(T).name();
return typeid(T).name();
#endif
}
}
template<typename Parser>