Skip to content
Open
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
4 changes: 4 additions & 0 deletions doc/BOOST_METAPARSE_STRING.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion doc/BOOST_METAPARSE_STRING_VALUE.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ 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.

[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]

Expand Down
5 changes: 4 additions & 1 deletion include/boost/metaparse/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
35 changes: 35 additions & 0 deletions include/boost/metaparse/v1/cpp17/impl/convert_string.hpp
Original file line number Diff line number Diff line change
@@ -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 <boost/metaparse/v1/string.hpp>

#include <cstddef> // for std::size_t
#include <utility> // for std::make_index_sequence

namespace boost
{
namespace metaparse
{
namespace v1
{
namespace impl
{
template<const auto& S>
struct convert_string {
template<std::size_t... Is>
static constexpr auto apply(std::index_sequence<Is...>) noexcept {
return ::boost::metaparse::v1::string<S[Is]...>{};
}
};
}
}
}
}

#endif

25 changes: 25 additions & 0 deletions include/boost/metaparse/v1/cpp17/string_value.hpp
Original file line number Diff line number Diff line change
@@ -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 <boost/metaparse/v1/impl/fixed_string.hpp>
#include <boost/metaparse/v1/cpp17/impl/convert_string.hpp>

#include <utility> // 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 auto fs = impl::make_fixed_string(s); \
return impl::convert_string<fs>::apply(std::make_index_sequence<fs.size() - 1>{}); \
}())

#endif

39 changes: 39 additions & 0 deletions include/boost/metaparse/v1/impl/fixed_string.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#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.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <cstddef> // for std::size_t

namespace boost
{
namespace metaparse
{
namespace v1
{
namespace impl
{
template<typename CharT, std::size_t N>
struct fixed_string {
const CharT* data;
constexpr fixed_string(const CharT (&s)[N]) noexcept
: data{s}
{}
constexpr CharT operator[](std::size_t i) const noexcept { return data[i]; }
constexpr std::size_t size() const noexcept { return N; }
};

template<typename CharT, std::size_t N>
Comment thread
denzor200 marked this conversation as resolved.
constexpr fixed_string<CharT, N> make_fixed_string(const CharT(&s)[N]) noexcept {
return {s};
}
}
}
}
}

#endif

21 changes: 15 additions & 6 deletions include/boost/metaparse/v1/string_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <boost/metaparse/v1/string.hpp>
#include <boost/metaparse/config.hpp>

#ifdef BOOST_METAPARSE_V1_STRING_VALUE
#error BOOST_METAPARSE_V1_STRING_VALUE already defined
#endif
#if BOOST_METAPARSE_STD >= 2017
# include <boost/metaparse/v1/cpp17/string_value.hpp>
#else

# include <boost/metaparse/v1/string.hpp>

# 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
Expand Down
2 changes: 2 additions & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import testing ;
import config : requires ;

project :
requirements
Expand Down Expand Up @@ -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 ]
Expand Down
24 changes: 24 additions & 0 deletions test/string_value_unlimited_cxx17.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/metaparse/string.hpp>
#include <boost/metaparse/string_value.hpp>

#include <boost/test/unit_test.hpp>

#include <type_traits>

BOOST_AUTO_TEST_CASE(test_string_value_unlimited_cxx17)
{
auto abcde = BOOST_METAPARSE_STRING_VALUE("abcde");

BOOST_MPL_ASSERT((
std::is_same<boost::metaparse::string<'a', 'b', 'c', 'd', 'e'>, decltype(abcde)>
));
}