summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/compileTimeFormatter.h79
-rw-r--r--libadhocutil/ctf-impl/printf-compat.h4
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp43
3 files changed, 21 insertions, 105 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h
index 33fe677..be57fee 100644
--- a/libadhocutil/compileTimeFormatter.h
+++ b/libadhocutil/compileTimeFormatter.h
@@ -1,25 +1,17 @@
#ifndef ADHOCUTIL_COMPILE_TIME_FORMATTER_H
#define ADHOCUTIL_COMPILE_TIME_FORMATTER_H
+#include <array>
#include <boost/preprocessor/control/iif.hpp> // IWYU pragma: keep
#include <boost/preprocessor/variadic/size.hpp> // IWYU pragma: keep
+#include <cstddef>
+#include <iostream>
#include <optional>
#include <sstream> // IWYU pragma: export
#include <type_traits>
// Mapped for for BOOST_PP_VARIADIC_SIZE, BOOST_PP... in tests
// IWYU pragma: no_include <boost/test/unit_test.hpp>
-#ifdef __cpp_nontype_template_parameter_class
-# define USE_FIXED_STRING
-#endif
-
-#ifdef USE_FIXED_STRING
-# define CtfString const auto
-# include <array>
-# include <iostream>
-#else
-# define CtfString const auto &
-#endif
namespace AdHoc {
// Template char utils
template<typename char_type>
@@ -37,7 +29,7 @@ namespace AdHoc {
}
// Template string utils
- template<CtfString S>
+ template<const auto S>
static constexpr auto
strlen()
{
@@ -59,7 +51,7 @@ namespace AdHoc {
return off;
}
- template<CtfString S, auto n, auto start = 0U, auto L = strlen<S>()>
+ template<const auto S, auto n, auto start = 0U, auto L = strlen<S>()>
static constexpr std::optional<decltype(start)>
strchr()
{
@@ -74,7 +66,7 @@ namespace AdHoc {
return off;
}
- template<CtfString S, auto n, auto start = 0U, auto L = strlen<S>()>
+ template<const auto S, auto n, auto start = 0U, auto L = strlen<S>()>
static constexpr decltype(L)
strchrnul()
{
@@ -85,10 +77,10 @@ namespace AdHoc {
return off;
}
- template<CtfString S, const auto L> class FormatterDetail;
+ template<const auto S, const auto L> class FormatterDetail;
/// Template used to apply parameters to a stream.
- template<CtfString S, auto L, auto pos, typename stream, typename, auto...> struct StreamWriter {
+ template<const auto S, auto L, auto pos, typename stream, typename, auto...> struct StreamWriter {
/// Write parameters to stream.
template<typename... Pn>
static void
@@ -99,7 +91,7 @@ namespace AdHoc {
};
/// Helper to simplify implementations of StreamWriter.
- template<CtfString S, auto L, auto pos, typename stream> struct StreamWriterBase {
+ template<const auto S, auto L, auto pos, typename stream> struct StreamWriterBase {
/// Continue processing parameters.
template<typename... Pn>
static inline void
@@ -110,12 +102,12 @@ namespace AdHoc {
};
#define StreamWriterT(...) \
- template<CtfString S, auto L, auto pos, typename stream, auto... sn> \
+ template<const auto S, auto L, auto pos, typename stream, auto... sn> \
struct StreamWriter<S, L, pos, stream, void, '%', __VA_ARGS__, sn...> : \
public StreamWriterBase<S, L, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__) + pos, stream>
#define StreamWriterTP(P, ...) \
- template<CtfString S, auto L, auto pos, typename stream, auto P, auto... sn> \
+ template<const auto S, auto L, auto pos, typename stream, auto P, auto... sn> \
struct StreamWriter<S, L, pos, stream, void, '%', __VA_ARGS__, sn...> : \
public StreamWriterBase<S, L, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__) + pos, stream>
@@ -159,10 +151,10 @@ namespace AdHoc {
* Compile time string formatter.
* @param S the format string.
*/
- template<CtfString S, const auto L> class FormatterDetail {
+ template<const auto S, const auto L> class FormatterDetail {
private:
using strlen_t = decltype(strlen<S>());
- template<CtfString, auto, auto, typename> friend struct StreamWriterBase;
+ template<const auto, auto, auto, typename> friend struct StreamWriterBase;
public:
/// The derived charater type of the format string.
@@ -246,18 +238,18 @@ namespace AdHoc {
};
};
-#ifdef USE_FIXED_STRING
- // New C++20 implementation
namespace support {
template<typename CharT, std::size_t N> class basic_fixed_string : public std::array<CharT, N> {
public:
// cppcheck-suppress noExplicitConstructor
+ // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-explicit-conversions)
constexpr basic_fixed_string(const CharT (&str)[N + 1])
{
for (decltype(N) x = 0; x < N; x++) {
this->at(x) = str[x];
}
}
+ // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
constexpr basic_fixed_string(const CharT * str, decltype(N) len)
{
for (decltype(N) x = 0; x < len; x++) {
@@ -267,7 +259,8 @@ namespace AdHoc {
};
template<typename CharT, std::size_t N>
- basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string<CharT, N - 1>;
+ // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
+ basic_fixed_string(const CharT (&str)[N])->basic_fixed_string<CharT, N - 1>;
}
template<const support::basic_fixed_string Str> class LiteralFormatter : public FormatterDetail<Str, Str.size()> {
@@ -278,7 +271,7 @@ namespace AdHoc {
public FormatterDetail<support::basic_fixed_string<typename std::decay<decltype(S[0])>::type, L>(S, L), L> {
};
-# define AdHocFormatter(name, str) using name = ::AdHoc::LiteralFormatter<str>
+#define AdHocFormatter(name, str) using name = ::AdHoc::LiteralFormatter<str>
template<const support::basic_fixed_string Str, typename... Pn>
inline auto
@@ -301,47 +294,11 @@ namespace AdHoc {
return scprintf<Str>(std::cout, pn...);
}
-#else
- // Classic pre-C++20 implementation
-# include "unique.h"
- template<const auto & S, decltype(strlen<S>()) L = strlen<S>()> class Formatter : public FormatterDetail<S, L> {
- };
-
-# define AdHocFormatterTypedef(name, str, id) \
- inline constexpr auto id = str; \
- using name = ::AdHoc::Formatter<id>
-# define AdHocFormatter(name, str) AdHocFormatterTypedef(name, str, MAKE_UNIQUE(name))
-
-#endif
-
namespace literals {
-#ifdef USE_FIXED_STRING
template<const support::basic_fixed_string Str> constexpr inline auto operator""_fmt() noexcept
{
return AdHoc::FormatterDetail<Str, Str.size()>();
}
-#else
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wpedantic"
-# ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template"
-# endif
- /// CTF format string holder
- template<typename T, T... t> struct FMT {
- /// CTF format string
- // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
- static constexpr char fmtstr[] = {t...};
- };
- template<typename T, T... t> inline auto operator""_fmt() noexcept
- {
- return AdHoc::FormatterDetail<FMT<T, t...>::fmtstr, sizeof...(t)>();
- }
-# ifdef __clang__
-# pragma clang diagnostic pop
-# endif
-# pragma GCC diagnostic pop
-#endif
}
}
diff --git a/libadhocutil/ctf-impl/printf-compat.h b/libadhocutil/ctf-impl/printf-compat.h
index 1ca30c3..40508f7 100644
--- a/libadhocutil/ctf-impl/printf-compat.h
+++ b/libadhocutil/ctf-impl/printf-compat.h
@@ -131,7 +131,7 @@ namespace AdHoc {
BOOST_PP_CAT(data, n)
#define ISDIGIT(z, n, data) &&isdigit(BOOST_PP_CAT(data, BOOST_PP_ADD(n, 1)))
#define FMTWIDTH(unused, d, data) \
- template<CtfString S, auto L, auto pos, typename stream, BOOST_PP_REPEAT(BOOST_PP_ADD(d, 1), AUTON, n), auto nn, \
+ template<const auto S, auto L, auto pos, typename stream, BOOST_PP_REPEAT(BOOST_PP_ADD(d, 1), AUTON, n), auto nn, \
auto... sn> \
struct StreamWriter<S, L, pos, stream, \
typename std::enable_if<ispositivedigit(n0) BOOST_PP_REPEAT(d, ISDIGIT, n) && !isdigit(nn)>::type, '%', \
@@ -147,7 +147,7 @@ namespace AdHoc {
};
BOOST_PP_REPEAT(6, FMTWIDTH, void)
#define FMTPRECISION(unused, d, data) \
- template<CtfString S, auto L, auto pos, typename stream, BOOST_PP_REPEAT(BOOST_PP_ADD(d, 1), AUTON, n), auto nn, \
+ template<const auto S, auto L, auto pos, typename stream, BOOST_PP_REPEAT(BOOST_PP_ADD(d, 1), AUTON, n), auto nn, \
auto... sn> \
struct StreamWriter<S, L, pos, stream, \
typename std::enable_if<isdigit(n0) BOOST_PP_REPEAT(d, ISDIGIT, n) && !isdigit(nn)>::type, '%', '.', \
diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp
index fc45dba..a79e369 100644
--- a/libadhocutil/unittests/testCompileTimeFormatter.cpp
+++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp
@@ -10,9 +10,9 @@
#include <cxxabi.h>
#include <definedDirs.h>
#include <fileUtils.h>
+#include <iostream>
#include <locale>
#include <memory>
-#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
@@ -93,45 +93,6 @@ namespace AdHoc {
};
}
-#ifndef __cpp_nontype_template_parameter_class
-// Compile string util assertions
-static_assert(strlen<formatEdgeCaseEmpty>() == 0);
-static_assert(strlen<formatEdgeCaseSingle>() == 1);
-static_assert(strlen<formatEdgeCaseFormatLonely>() == 2);
-static_assert(strlen<formatStringLiteral>() == 7);
-static_assert(strlen<formatStringLong>() == 246);
-
-static_assert(!strchr<formatEdgeCaseEmpty, 't'>());
-static_assert(!strchr<formatEdgeCaseSingle, 't'>());
-static_assert(*strchr<formatEdgeCaseSingle, '1'>() == 0);
-static_assert(*strchr<formatEdgeCaseFormatLonely, '%'>() == 0);
-static_assert(*strchr<formatEdgeCaseFormatLonely, '?'>() == 1);
-static_assert(*strchr<formatStringLiteral, 'e'>() == 3);
-static_assert(!strchr<formatStringLiteral, 'f'>());
-static_assert(*strchr<formatStringLiteral, 'e', 3U>() == 3);
-static_assert(!strchr<formatStringLiteral, 'e', 4U>());
-static_assert(!strchr<formatStringLiteral, 'f', 3U>());
-
-static_assert(strchrnul<formatEdgeCaseEmpty, 't'>() == 0);
-static_assert(strchrnul<formatEdgeCaseSingle, 't'>() == 1);
-static_assert(strchrnul<formatEdgeCaseSingle, '1'>() == 0);
-static_assert(strchrnul<formatEdgeCaseFormatLonely, '%'>() == 0);
-static_assert(strchrnul<formatEdgeCaseFormatLonely, '?'>() == 1);
-static_assert(strchrnul<formatStringLiteral, 'e'>() == 3);
-static_assert(strchrnul<formatStringLiteral, 'f'>() == 7);
-static_assert(strchrnul<formatStringLiteral, 'e', 3U>() == 3);
-static_assert(strchrnul<formatStringLiteral, 'e', 4U>() == 7);
-static_assert(strchrnul<formatStringLiteral, 'f', 3U>() == 7);
-
-static_assert(strchrnul<formatEdgeCaseEmpty, 't'>() == 0);
-static_assert(strchrnul<formatEdgeCaseSingle, 't'>() == 1);
-static_assert(strchrnul<formatEdgeCaseSingle, '1'>() == 0);
-static_assert(strchrnul<formatEdgeCaseFormatLonely, '%'>() == 0);
-static_assert(strchrnul<formatEdgeCaseFormatLonely, '?'>() == 1);
-static_assert(strchrnul<formatStringLiteral, 'e'>() == 3);
-static_assert(strchrnul<formatStringLiteral, 'f'>() == 7);
-#endif
-
BOOST_FIXTURE_TEST_SUITE(TestStreamWrite, std::stringstream)
BOOST_AUTO_TEST_CASE(empty)
@@ -464,7 +425,6 @@ BOOST_AUTO_TEST_CASE(smartptr)
smartptr_fmt::get(shrd);
}
-#ifdef __cpp_nontype_template_parameter_class
BOOST_AUTO_TEST_CASE(literal_format_string)
{
std::stringstream str;
@@ -511,7 +471,6 @@ BOOST_AUTO_TEST_CASE(scprintf_get_no_args)
auto stng = scprintf<"Some literal format string.">();
BOOST_CHECK_EQUAL(stng, "Some literal format string.");
}
-#endif
using namespace AdHoc::literals;