1 #ifndef OOKII_STRING_HELPER_H_
4 #define OOKII_STRING_HELPER_H_
13 #include <string_view>
21 using default_char_type = wchar_t;
23 using default_char_type = char;
41 : _case_sensitive{case_sensitive},
52 template<
typename Range1,
typename Range2>
60 return std::lexicographical_compare(begin(left), end(left), begin(right), end(right), std::less<>{});
64 return std::lexicographical_compare(begin(left), end(left), begin(right), end(right), [
this](
auto left,
auto right)
66 return std::toupper(left, _locale) < std::toupper(right, _locale);
89 char_less(
bool case_sensitive =
true, std::locale loc = {})
90 : _case_sensitive{case_sensitive},
100 template<
typename CharType>
109 return std::toupper(left, _locale) < std::toupper(right, _locale);
114 bool _case_sensitive;
125 template<
typename CharType,
typename Traits>
126 bool string_equal_case_insensitive(std::basic_string_view<CharType, Traits> string1, std::basic_string_view<CharType, Traits> string2,
const std::locale &locale = {})
128 return std::equal(string1.begin(), string1.end(), string2.begin(), string2.end(), [&locale](
auto left,
auto right)
130 return std::toupper(left, locale) == std::toupper(right, locale);
146 template<
typename CharType,
size_t Length>
147 constexpr
const std::array<CharType, Length>
literal_cast(
const char (&value)[Length])
149 std::array<CharType, Length> result{};
150 std::copy(std::begin(value), std::end(value), result.begin());
164 template<
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
171 static std::basic_string<CharType, Traits, Alloc>
from_bytes(std::string_view value,
const std::locale &loc = {})
173 std::basic_string<CharType, Traits, Alloc> result;
174 auto &facet = std::use_facet<std::ctype<CharType>>(loc);
175 result.reserve(value.length());
176 std::transform(value.begin(), value.end(), std::back_inserter(result), [&facet](
auto c)
178 return facet.widen(c);
188 template<
typename Traits,
typename Alloc>
194 static std::basic_string<char, Traits, Alloc>
from_bytes(std::string_view value,
const std::locale & = {})
196 return std::basic_string<char, Traits, Alloc>{value};
210 template<
typename T,
typename CharType,
typename Traits = std::
char_traits<CharType>,
typename Alloc = std::allocator<CharType>>
217 static std::optional<T>
from_string(std::basic_string_view<CharType, Traits> value,
const std::locale &loc = {})
219 std::basic_istringstream<CharType> stream{std::basic_string<CharType, Traits, Alloc>{value}};
223 stream.unsetf(std::ios::dec);
224 stream.unsetf(std::ios::oct);
225 stream.unsetf(std::ios::hex);
228 if (!stream || !stream.eof())
243 template<
typename CharType,
typename Traits,
typename Alloc>
244 struct lexical_convert<std::basic_string<CharType, Traits, Alloc>, CharType, Traits, Alloc>
249 static std::optional<std::basic_string<CharType, Traits, Alloc>>
from_string(std::basic_string_view<CharType, Traits> value,
const std::locale &)
251 return {std::basic_string<CharType, Traits, Alloc>{value}};
262 template<
typename CharType,
typename Traits = std::
char_traits<CharType>>
268 using iterator_concept = std::forward_iterator_tag;
269 using value_type = std::basic_string_view<CharType, Traits>;
270 using difference_type = std::ptrdiff_t;
271 using pointer = value_type*;
272 using reference = value_type&;
274 iterator() noexcept =
default;
276 iterator(value_type value, CharType separator) noexcept
278 _separator{separator}
283 iterator &operator++() noexcept
289 iterator operator++(
int) noexcept
291 iterator temp = *
this;
296 value_type operator*()
const noexcept
301 bool operator==(
const iterator &other)
const noexcept
303 return _value == other._value && _remaining == other._remaining;
307 void next_value() noexcept
309 if (_remaining.length() != 0)
311 auto index = _remaining.find_first_of(_separator);
312 _value = _remaining.substr(0, index);
313 if (index == std::string_view::npos)
319 _remaining = _remaining.substr(index + 1);
329 value_type _remaining;
330 CharType _separator{};
337 tokenize(
typename iterator::value_type value, CharType separator) noexcept
339 _separator{separator}
346 return iterator{_value, _separator};
351 iterator
end() const noexcept
357 typename iterator::value_type _value;
368 template<
typename CharType,
typename Traits>
369 std::optional<std::basic_string_view<CharType, Traits>>
strip_prefix(std::basic_string_view<CharType, Traits> value,
370 std::basic_string_view<CharType, Traits> prefix)
372 if (value.starts_with(prefix))
374 return value.substr(prefix.length());
388 template<
typename CharType,
typename Traits>
389 std::tuple<std::basic_string_view<CharType, Traits>, std::optional<std::basic_string_view<CharType, Traits>>>
split_once(
390 std::basic_string_view<CharType, Traits> value, CharType separator)
392 auto index = value.find(separator);
393 if (index == std::basic_string_view<CharType, Traits>::npos)
398 return {value.substr(0, index), value.substr(index + 1)};
A pseudo-range for string tokenization.
Definition: string_helper.h:264
iterator end() const noexcept
Gets an iterator that will compare equal once the iterator returned by begin() no longer has any toke...
Definition: string_helper.h:351
tokenize(typename iterator::value_type value, CharType separator) noexcept
Initializes a new instance of the tokenize class.
Definition: string_helper.h:337
iterator begin() const noexcept
Gets a forward iterator to the first token.
Definition: string_helper.h:344
Namespace containing the core Ookii.CommandLine.Cpp types.
Definition: command_line_argument.h:16
std::optional< std::basic_string_view< CharType, Traits > > strip_prefix(std::basic_string_view< CharType, Traits > value, std::basic_string_view< CharType, Traits > prefix)
Removes a prefix from a string.
Definition: string_helper.h:369
constexpr const std::array< CharType, Length > literal_cast(const char(&value)[Length])
Converts a simple ASCII string literal to the specified character type at compile time.
Definition: string_helper.h:147
std::tuple< std::basic_string_view< CharType, Traits >, std::optional< std::basic_string_view< CharType, Traits > > > split_once(std::basic_string_view< CharType, Traits > value, CharType separator)
Splits a string on the first occurrence of a separator.
Definition: string_helper.h:389
bool string_equal_case_insensitive(std::basic_string_view< CharType, Traits > string1, std::basic_string_view< CharType, Traits > string2, const std::locale &locale={})
Compares two strings, ignoring their case.
Definition: string_helper.h:126
A version of the std::less predicate for characters that supports case insensitive comparison.
Definition: string_helper.h:79
bool operator()(CharType &&left, CharType &&right) const
Compares two characters.
Definition: string_helper.h:101
char_less(bool case_sensitive=true, std::locale loc={})
Initializes a new instance of the char_less class.
Definition: string_helper.h:89
int is_transparent
Indicates that this function accepts any type and uses perfect forwarding.
Definition: string_helper.h:82
static std::optional< std::basic_string< CharType, Traits, Alloc > > from_string(std::basic_string_view< CharType, Traits > value, const std::locale &)
Convert a string to the specified type.
Definition: string_helper.h:249
Template class used to convert strings to strongly typed argument values.
Definition: string_helper.h:212
static std::optional< T > from_string(std::basic_string_view< CharType, Traits > value, const std::locale &loc={})
Convert a string to the specified type.
Definition: string_helper.h:217
static std::basic_string< char, Traits, Alloc > from_bytes(std::string_view value, const std::locale &={})
Converts a string to the specified character type.
Definition: string_helper.h:194
Performs a simple conversion of a narrow character string to a specified character type.
Definition: string_helper.h:166
static std::basic_string< CharType, Traits, Alloc > from_bytes(std::string_view value, const std::locale &loc={})
Converts a string to the specified character type.
Definition: string_helper.h:171
A version of the std::less predicate for strings that supports case insensitive comparison.
Definition: string_helper.h:30
int is_transparent
Indicates that this function accepts any type and uses perfect forwarding.
Definition: string_helper.h:33
string_less(bool case_sensitive=true, std::locale loc={})
Initializes a new instance of the string_less class.
Definition: string_helper.h:40
bool operator()(Range1 &&left, Range2 &&right) const
Compares two strings.
Definition: string_helper.h:53