Skip to content

Commit 2486e5e

Browse files
committed
added prefix and postfix support to fixed_string
1 parent d2740d5 commit 2486e5e

1 file changed

Lines changed: 72 additions & 42 deletions

File tree

include/strtype/strtype.hpp

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#pragma once
22
#include <algorithm>
33
#include <array>
4-
#include <cstdint>
54
#include <compare>
5+
#include <cstdint>
66
#include <string_view>
77
#include <type_traits>
88

@@ -84,6 +84,38 @@ namespace strtype
8484
return fixed_string<SIZE>(copy.data());
8585
}
8686

87+
template <unsigned M>
88+
consteval auto prefix(char const (&value)[M]) const noexcept
89+
{
90+
return prefix(fixed_string<M - 1> {value});
91+
}
92+
93+
template <size_t M>
94+
consteval auto prefix(fixed_string<M> value) const noexcept -> fixed_string<N + M>
95+
{
96+
std::array<char, N + M> result {};
97+
for(size_t i = 0; i < M; ++i) result[i] = value[i];
98+
for(size_t i = 0; i < N; ++i) result[M + i] = buf[i];
99+
100+
return fixed_string<N + M>(result.data());
101+
}
102+
103+
template <unsigned M>
104+
consteval auto postfix(char const (&value)[M]) const noexcept
105+
{
106+
return postfix(fixed_string<M - 1> {value});
107+
}
108+
109+
template <size_t M>
110+
consteval auto postfix(fixed_string<M> value) const noexcept -> fixed_string<N + M>
111+
{
112+
std::array<char, N + M> result {};
113+
for(size_t i = 0; i < N; ++i) result[i] = buf[i];
114+
for(size_t i = 0; i < M; ++i) result[N + i] = value[i];
115+
116+
return fixed_string<N + M>(result.data());
117+
}
118+
87119
constexpr auto begin() const noexcept { return buf; }
88120
constexpr auto cbegin() const noexcept { return buf; }
89121
constexpr auto end() const noexcept { return &buf[N]; }
@@ -178,9 +210,9 @@ namespace strtype
178210
// figure out if the Value is either an enum value of the given enum type, or equivalent to the underlying
179211
// value;
180212
template <typename T, auto Value>
181-
concept IsEnumValueOrUnderlying = IsValidStringifyableEnum<T> &&
182-
(std::is_same_v<decltype(Value), T> ||
183-
std::is_same_v<decltype(Value), std::underlying_type_t<T>>);
213+
concept IsEnumValueOrUnderlying =
214+
IsValidStringifyableEnum<T> &&
215+
(std::is_same_v<decltype(Value), T> || std::is_same_v<decltype(Value), std::underlying_type_t<T>>);
184216

185217
template <typename T, auto Value, bool ApplyOffset = false>
186218
requires(IsEnumValueOrUnderlying<T, Value>)
@@ -638,9 +670,9 @@ namespace strtype
638670
T* value_buffer = nullptr) constexpr {
639671
size_t count = 0;
640672

641-
constexpr auto get_and_fill_valid_enum_value =
642-
[]<auto Index>(auto& count, std::string_view* str_buffer, T* value_buffer) constexpr
643-
{
673+
constexpr auto get_and_fill_valid_enum_value = []<auto Index>(auto& count,
674+
std::string_view* str_buffer,
675+
T* value_buffer) constexpr {
644676
constexpr auto get_enum_name = []<T value>() constexpr {
645677
return details::stringify_value_impl<value,
646678
details::get_known_offset<T {enum_information<T>::BEGIN}>()>();
@@ -693,34 +725,34 @@ namespace strtype
693725
constexpr underlying_t remainder = (End - Begin) % PACK_SIZE;
694726
constexpr underlying_t iterations = (End - Begin - remainder) / PACK_SIZE;
695727

696-
constexpr auto split_into_iteration_packs_and_invoke = []<std::underlying_type_t<T>... Indices>(
697-
std::integer_sequence<std::underlying_type_t<T>, Indices...>) constexpr
698-
{
699-
constexpr auto merge_results = []<typename... Ts>(Ts&&... arrays) constexpr {
700-
constexpr auto total_size = details::get_array_pack_size<Ts...>::value;
701-
std::array<std::string_view, total_size> res_string {};
702-
std::array<T, total_size> res_values {};
703-
size_t offset {0};
704-
constexpr auto fill =
705-
[](auto& dst_str, auto& dst_values, const auto& src, size_t& offset) constexpr {
706-
for(size_t i = 0; i < src.first.size(); ++offset, ++i)
707-
{
708-
dst_str[offset] = src.first[i];
709-
dst_values[offset] = src.second[i];
710-
}
711-
};
712-
(fill(res_string, res_values, arrays, offset), ...);
713-
return std::pair {res_string, res_values};
714-
};
715-
716-
// returns all valid enum values for the given range [Offset, Offset + Count) as a
717-
return merge_results(stringify<T>(details::make_offset_sequence<Begin + (Indices * PACK_SIZE),
718-
PACK_SIZE,
719-
std::underlying_type_t<T>>())...,
720-
stringify<T>(details::make_offset_sequence<Begin + (iterations * PACK_SIZE),
721-
remainder,
722-
std::underlying_type_t<T>>()));
723-
};
728+
constexpr auto split_into_iteration_packs_and_invoke =
729+
[]<std::underlying_type_t<T>... Indices>(
730+
std::integer_sequence<std::underlying_type_t<T>, Indices...>) constexpr {
731+
constexpr auto merge_results = []<typename... Ts>(Ts&&... arrays) constexpr {
732+
constexpr auto total_size = details::get_array_pack_size<Ts...>::value;
733+
std::array<std::string_view, total_size> res_string {};
734+
std::array<T, total_size> res_values {};
735+
size_t offset {0};
736+
constexpr auto fill =
737+
[](auto& dst_str, auto& dst_values, const auto& src, size_t& offset) constexpr {
738+
for(size_t i = 0; i < src.first.size(); ++offset, ++i)
739+
{
740+
dst_str[offset] = src.first[i];
741+
dst_values[offset] = src.second[i];
742+
}
743+
};
744+
(fill(res_string, res_values, arrays, offset), ...);
745+
return std::pair {res_string, res_values};
746+
};
747+
748+
// returns all valid enum values for the given range [Offset, Offset + Count) as a
749+
return merge_results(stringify<T>(details::make_offset_sequence<Begin + (Indices * PACK_SIZE),
750+
PACK_SIZE,
751+
std::underlying_type_t<T>>())...,
752+
stringify<T>(details::make_offset_sequence<Begin + (iterations * PACK_SIZE),
753+
remainder,
754+
std::underlying_type_t<T>>()));
755+
};
724756
return split_into_iteration_packs_and_invoke(
725757
std::make_integer_sequence<std::underlying_type_t<T>, iterations>());
726758
}
@@ -745,11 +777,9 @@ namespace strtype
745777

746778
// prepares an std::index_sequence<> where the indices are every bit value with added 0. I.e. it's a range
747779
// that looks like: { 0, 1, 2, 4, 8, 16, 32, ..., 1 << (sizeof(underlying_t) * 8) }
748-
constexpr auto bit_shift_indices = []<size_t... Indices>(std::index_sequence<Indices...>) constexpr
749-
{
780+
constexpr auto bit_shift_indices = []<size_t... Indices>(std::index_sequence<Indices...>) constexpr {
750781
return std::index_sequence<0, size_t {1} << Indices...> {};
751-
}
752-
(std::make_index_sequence<BITS>());
782+
}(std::make_index_sequence<BITS>());
753783

754784
return stringify<T>(bit_shift_indices);
755785
}
@@ -857,14 +887,14 @@ namespace strtype
857887
constexpr auto value = stringify_typename<T>();
858888
constexpr auto end = [](std::string_view value) {
859889
auto offset = value.find('<');
860-
auto end = value.rfind(':', offset);
861-
return (end != std::string_view::npos && end > 0 && value[end - 1] == ':') ? end -1 : 0;
890+
auto end = value.rfind(':', offset);
891+
return (end != std::string_view::npos && end > 0 && value[end - 1] == ':') ? end - 1 : 0;
862892
}(value);
863893

864894
return value.template substr<0, end>();
865895
}
866896

867-
template<typename T>
897+
template <typename T>
868898
consteval auto is_templated_type() noexcept -> bool
869899
{
870900
constexpr auto value = stringify_typename<T>();

0 commit comments

Comments
 (0)