From 2f8de7e29f25d356e25825cca91f9eed5ccf83c5 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Sun, 31 Aug 2025 17:41:33 +0300 Subject: [PATCH 1/3] Make BOOST_METAPARSE_STRING_VALUE unlimited in C++17 --- doc/BOOST_METAPARSE_STRING.qbk | 4 ++ doc/BOOST_METAPARSE_STRING_VALUE.qbk | 8 +++- include/boost/metaparse/config.hpp | 5 ++- .../v1/cpp17/impl/convert_string.hpp | 35 ++++++++++++++++++ .../metaparse/v1/cpp17/impl/fixed_string.hpp | 37 +++++++++++++++++++ .../boost/metaparse/v1/cpp17/string_value.hpp | 25 +++++++++++++ include/boost/metaparse/v1/string_value.hpp | 21 ++++++++--- test/Jamfile.v2 | 2 + test/string_value_unlimited_cxx17.cpp | 24 ++++++++++++ 9 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 include/boost/metaparse/v1/cpp17/impl/convert_string.hpp create mode 100644 include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp create mode 100644 include/boost/metaparse/v1/cpp17/string_value.hpp create mode 100644 test/string_value_unlimited_cxx17.cpp diff --git a/doc/BOOST_METAPARSE_STRING.qbk b/doc/BOOST_METAPARSE_STRING.qbk index 5168e4a..28b65a2 100644 --- a/doc/BOOST_METAPARSE_STRING.qbk +++ b/doc/BOOST_METAPARSE_STRING.qbk @@ -21,6 +21,10 @@ string literal. The macro requires C++11. The maximal length of the string is limited. This limit is defined by the `BOOST_METAPARSE_LIMIT_STRING_SIZE` macro. +For C++17 and later, consider using +[link BOOST_METAPARSE_STRING_VALUE `BOOST_METAPARSE_STRING_VALUE`] +instead, as it doesn't have these limitations. + On platforms where `BOOST_METAPARSE_STRING` is not supported, the `string.hpp` header defines the `BOOST_METAPARSE_V1_CONFIG_NO_BOOST_METAPARSE_STRING` macro. Defining this macro before including the header disables the diff --git a/doc/BOOST_METAPARSE_STRING_VALUE.qbk b/doc/BOOST_METAPARSE_STRING_VALUE.qbk index 0c14e4d..a434a95 100644 --- a/doc/BOOST_METAPARSE_STRING_VALUE.qbk +++ b/doc/BOOST_METAPARSE_STRING_VALUE.qbk @@ -16,7 +16,13 @@ This is a macro. [h1 Description] This is a convenience macro for creating instances of the string types created -using [link BOOST_METAPARSE_STRING `BOOST_METAPARSE_STRING`]. +using [link BOOST_METAPARSE_STRING `BOOST_METAPARSE_STRING`]. The macro +requires C++11. + +[*C++11]: The maximum length of these strings is controlled by the +`BOOST_METAPARSE_LIMIT_STRING_SIZE` macro. + +[*C++17]: The macro uses constexpr string literal. [h1 Header] diff --git a/include/boost/metaparse/config.hpp b/include/boost/metaparse/config.hpp index f1af39e..8d59546 100644 --- a/include/boost/metaparse/config.hpp +++ b/include/boost/metaparse/config.hpp @@ -40,8 +40,11 @@ || (defined _MSC_VER && _MSC_VER >= 1900) \ ) \ && (!defined BOOST_GCC || BOOST_GCC >= 40700) +# if !defined BOOST_NO_CXX17_DEDUCTION_GUIDES -# if !defined BOOST_NO_CXX14_CONSTEXPR +# define BOOST_METAPARSE_STD 2017 + +# elif !defined BOOST_NO_CXX14_CONSTEXPR # define BOOST_METAPARSE_STD 2014 diff --git a/include/boost/metaparse/v1/cpp17/impl/convert_string.hpp b/include/boost/metaparse/v1/cpp17/impl/convert_string.hpp new file mode 100644 index 0000000..44bfbbb --- /dev/null +++ b/include/boost/metaparse/v1/cpp17/impl/convert_string.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_METAPARSE_V1_CPP17_IMPL_CONVERT_STRING_HPP +#define BOOST_METAPARSE_V1_CPP17_IMPL_CONVERT_STRING_HPP + +// Copyright Denis Mikhailov 2025. +// 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) + +#include + +#include // for std::size_t +#include // for std::make_index_sequence + +namespace boost +{ + namespace metaparse + { + namespace v1 + { + namespace impl + { + template + struct convert_string { + template + static constexpr auto apply(std::index_sequence) noexcept { + return ::boost::metaparse::v1::string{}; + } + }; + } + } + } +} + +#endif + diff --git a/include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp b/include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp new file mode 100644 index 0000000..b586e19 --- /dev/null +++ b/include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_METAPARSE_V1_CPP17_IMPL_FIXED_STRING_HPP +#define BOOST_METAPARSE_V1_CPP17_IMPL_FIXED_STRING_HPP + +// Copyright Denis Mikhailov 2025. +// 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) + +#include // for std::size_t + +namespace boost +{ + namespace metaparse + { + namespace v1 + { + namespace impl + { + template + struct fixed_string { + const CharT* data; + constexpr fixed_string(const CharT (&s)[N]) noexcept + : data{s} + {} + constexpr auto operator[](std::size_t i) const noexcept { return data[i]; } + constexpr std::size_t size() const noexcept { return N; } + }; + + template + fixed_string(const CharT(&)[N]) -> fixed_string; + } + } + } +} + +#endif + diff --git a/include/boost/metaparse/v1/cpp17/string_value.hpp b/include/boost/metaparse/v1/cpp17/string_value.hpp new file mode 100644 index 0000000..f31a704 --- /dev/null +++ b/include/boost/metaparse/v1/cpp17/string_value.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_METAPARSE_V1_CPP17_STRING_VALUE_HPP +#define BOOST_METAPARSE_V1_CPP17_STRING_VALUE_HPP + +// Copyright Denis Mikhailov 2025. +// 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) + +#include +#include + +#include // for std::make_index_sequence + +#ifdef BOOST_METAPARSE_V1_STRING_VALUE +#error BOOST_METAPARSE_V1_STRING_VALUE already defined +#endif + +#define BOOST_METAPARSE_V1_STRING_VALUE(s) ([]{ \ + namespace impl = ::boost::metaparse::v1::impl; \ + static constexpr impl::fixed_string fs(s); \ + return impl::convert_string::apply(std::make_index_sequence{}); \ +}()) + +#endif + diff --git a/include/boost/metaparse/v1/string_value.hpp b/include/boost/metaparse/v1/string_value.hpp index 6edc6ae..81d64e3 100644 --- a/include/boost/metaparse/v1/string_value.hpp +++ b/include/boost/metaparse/v1/string_value.hpp @@ -2,18 +2,27 @@ #define BOOST_METAPARSE_V1_STRING_VALUE_HPP // Copyright Abel Sinkovics (abel@sinkovics.hu) 2021. +// Copyright Denis Mikhailov 2025. // 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) -#include +#include -#ifdef BOOST_METAPARSE_V1_STRING_VALUE -#error BOOST_METAPARSE_V1_STRING_VALUE already defined -#endif +#if BOOST_METAPARSE_STD >= 2017 +# include +#else + +# include + +# ifdef BOOST_METAPARSE_V1_STRING_VALUE +# error BOOST_METAPARSE_V1_STRING_VALUE already defined +# endif + +# ifdef BOOST_METAPARSE_V1_STRING +# define BOOST_METAPARSE_V1_STRING_VALUE(s) (BOOST_METAPARSE_V1_STRING(s){}) +# endif -#ifdef BOOST_METAPARSE_V1_STRING -#define BOOST_METAPARSE_V1_STRING_VALUE(s) (BOOST_METAPARSE_V1_STRING(s){}) #endif #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 286395c..d5149c1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,4 +1,5 @@ import testing ; +import config : requires ; project : requirements @@ -103,6 +104,7 @@ test-suite metaparse-unit-tests : [ compile string_iterator_tag.cpp ] [ compile string_tag.cpp ] [ compile string_value.cpp ] + [ compile string_value_unlimited_cxx17.cpp : [ requires cxx17_deduction_guides ] ] [ compile swap.cpp ] [ compile token.cpp ] [ compile-fail too_long_string.cpp ] diff --git a/test/string_value_unlimited_cxx17.cpp b/test/string_value_unlimited_cxx17.cpp new file mode 100644 index 0000000..1e04069 --- /dev/null +++ b/test/string_value_unlimited_cxx17.cpp @@ -0,0 +1,24 @@ +// Copyright Denis Mikhailov 2025. +// 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) + +#define BOOST_TEST_MODULE string_value_unlimited_cxx17 + +#define BOOST_METAPARSE_LIMIT_STRING_SIZE 4 +#include +#include + +#include + +#include + +BOOST_AUTO_TEST_CASE(test_string_value_unlimited_cxx17) +{ + auto abcde = BOOST_METAPARSE_STRING_VALUE("abcde"); + + BOOST_MPL_ASSERT(( + std::is_same, decltype(abcde)> + )); +} + From ff49be022c57bbd30705d20627893475e1d9996d Mon Sep 17 00:00:00 2001 From: denzor200 Date: Sun, 31 Aug 2025 23:15:34 +0300 Subject: [PATCH 2/3] Add important line in the doc --- doc/BOOST_METAPARSE_STRING_VALUE.qbk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/BOOST_METAPARSE_STRING_VALUE.qbk b/doc/BOOST_METAPARSE_STRING_VALUE.qbk index a434a95..1982c00 100644 --- a/doc/BOOST_METAPARSE_STRING_VALUE.qbk +++ b/doc/BOOST_METAPARSE_STRING_VALUE.qbk @@ -24,6 +24,8 @@ requires C++11. [*C++17]: The macro uses constexpr string literal. +[caution It is [*not recommended] to use an expression with BOOST_METAPARSE_STRING_VALUE as the argument of `decltype`, for example `decltype(BOOST_METAPARSE_STRING_VALUE("foo"))`. Although such constructs may compile successfully in some environments, they tend to be [*non-portable]. ] + [h1 Header] #include From 01effbb359be829ce15854ea4dafc774be6fd5d5 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Sat, 18 Oct 2025 03:56:52 +0300 Subject: [PATCH 3/3] fixed_string for C++11 --- include/boost/metaparse/v1/cpp17/string_value.hpp | 4 ++-- .../metaparse/v1/{cpp17 => }/impl/fixed_string.hpp | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) rename include/boost/metaparse/v1/{cpp17 => }/impl/fixed_string.hpp (69%) diff --git a/include/boost/metaparse/v1/cpp17/string_value.hpp b/include/boost/metaparse/v1/cpp17/string_value.hpp index f31a704..4d38c71 100644 --- a/include/boost/metaparse/v1/cpp17/string_value.hpp +++ b/include/boost/metaparse/v1/cpp17/string_value.hpp @@ -6,7 +6,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #include // for std::make_index_sequence @@ -17,7 +17,7 @@ #define BOOST_METAPARSE_V1_STRING_VALUE(s) ([]{ \ namespace impl = ::boost::metaparse::v1::impl; \ - static constexpr impl::fixed_string fs(s); \ + static constexpr auto fs = impl::make_fixed_string(s); \ return impl::convert_string::apply(std::make_index_sequence{}); \ }()) diff --git a/include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp b/include/boost/metaparse/v1/impl/fixed_string.hpp similarity index 69% rename from include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp rename to include/boost/metaparse/v1/impl/fixed_string.hpp index b586e19..8b9e47f 100644 --- a/include/boost/metaparse/v1/cpp17/impl/fixed_string.hpp +++ b/include/boost/metaparse/v1/impl/fixed_string.hpp @@ -1,5 +1,5 @@ -#ifndef BOOST_METAPARSE_V1_CPP17_IMPL_FIXED_STRING_HPP -#define BOOST_METAPARSE_V1_CPP17_IMPL_FIXED_STRING_HPP +#ifndef BOOST_METAPARSE_V1_IMPL_FIXED_STRING_HPP +#define BOOST_METAPARSE_V1_IMPL_FIXED_STRING_HPP // Copyright Denis Mikhailov 2025. // Distributed under the Boost Software License, Version 1.0. @@ -22,12 +22,14 @@ namespace boost constexpr fixed_string(const CharT (&s)[N]) noexcept : data{s} {} - constexpr auto operator[](std::size_t i) const noexcept { return data[i]; } + constexpr CharT operator[](std::size_t i) const noexcept { return data[i]; } constexpr std::size_t size() const noexcept { return N; } }; template - fixed_string(const CharT(&)[N]) -> fixed_string; + constexpr fixed_string make_fixed_string(const CharT(&s)[N]) noexcept { + return {s}; + } } } }