nfx-stringutils 0.3.0
Modern C++20 header-only library providing high-performance string utilities and zero-allocation splitting
Loading...
Searching...
No Matches
Utils.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 nfx
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
31
32#pragma once
33
34#include <cstdint>
35#include <optional>
36#include <string>
37#include <string_view>
38
39namespace nfx::string
40{
41 //=====================================================================
42 // String utilities
43 //=====================================================================
44
45 //----------------------------------------------
46 // String validation
47 //----------------------------------------------
48
56 [[nodiscard]] inline constexpr bool hasExactLength( std::string_view str, std::size_t expectedLength ) noexcept;
57
64 [[nodiscard]] inline constexpr bool isEmpty( std::string_view str ) noexcept;
65
73 [[nodiscard]] inline constexpr bool isNullOrWhiteSpace( std::string_view str ) noexcept;
74
82 [[nodiscard]] inline constexpr bool isAllDigits( std::string_view str ) noexcept;
83
84 //----------------------------------------------
85 // Character classification
86 //----------------------------------------------
87
94 [[nodiscard]] inline constexpr bool isWhitespace( char c ) noexcept;
95
102 [[nodiscard]] inline constexpr bool isDigit( char c ) noexcept;
103
110 [[nodiscard]] inline constexpr bool isAlpha( char c ) noexcept;
111
118 [[nodiscard]] inline constexpr bool isAlphaNumeric( char c ) noexcept;
119
126 [[nodiscard]] inline constexpr bool isHexDigit( char c ) noexcept;
127
128 //----------------------------------------------
129 // String operations
130 //----------------------------------------------
131
139 [[nodiscard]] inline constexpr bool startsWith( std::string_view str, std::string_view prefix ) noexcept;
140
148 [[nodiscard]] inline constexpr bool endsWith( std::string_view str, std::string_view suffix ) noexcept;
149
157 [[nodiscard]] inline constexpr bool contains( std::string_view str, std::string_view substr ) noexcept;
158
166 [[nodiscard]] inline constexpr bool equals( std::string_view lhs, std::string_view rhs ) noexcept;
167
175 [[nodiscard]] inline bool iequals( std::string_view lhs, std::string_view rhs ) noexcept;
176
185 [[nodiscard]] inline std::size_t count( std::string_view str, std::string_view substr ) noexcept;
186
196 [[nodiscard]] inline std::size_t countOverlapping( std::string_view str, std::string_view substr ) noexcept;
197
205 [[nodiscard]] inline constexpr std::size_t count( std::string_view str, char ch ) noexcept;
206
216 [[nodiscard]] inline std::string replace( std::string_view str, std::string_view oldStr, std::string_view newStr );
217
227 [[nodiscard]] inline std::string replaceAll( std::string_view str, std::string_view oldStr, std::string_view newStr );
228
238 template <typename Container>
239 [[nodiscard]] inline std::string join( const Container& elements, std::string_view delimiter );
240
251 template <typename Iterator>
252 [[nodiscard]] inline std::string join( Iterator begin, Iterator end, std::string_view delimiter );
253
262 [[nodiscard]] inline std::string reverse( std::string_view str );
263
273 [[nodiscard]] inline constexpr std::size_t indexOf( std::string_view str, std::string_view substr ) noexcept;
274
284 [[nodiscard]] inline constexpr std::size_t lastIndexOf( std::string_view str, std::string_view substr ) noexcept;
285
286 //----------------------------------------------
287 // String formatting and padding
288 //----------------------------------------------
289
299 [[nodiscard]] inline std::string padLeft( std::string_view str, std::size_t width, char fillChar = ' ' );
300
310 [[nodiscard]] inline std::string padRight( std::string_view str, std::size_t width, char fillChar = ' ' );
311
322 [[nodiscard]] inline std::string center( std::string_view str, std::size_t width, char fillChar = ' ' );
323
332 [[nodiscard]] inline std::string repeat( std::string_view str, std::size_t count );
333
334 //----------------------------------------------
335 // Substring extraction
336 //----------------------------------------------
337
346 [[nodiscard]] inline constexpr std::string_view substringBefore( std::string_view str, std::string_view delimiter ) noexcept;
347
356 [[nodiscard]] inline constexpr std::string_view substringAfter( std::string_view str, std::string_view delimiter ) noexcept;
357
366 [[nodiscard]] inline constexpr std::string_view substringBeforeLast( std::string_view str, std::string_view delimiter ) noexcept;
367
376 [[nodiscard]] inline constexpr std::string_view substringAfterLast( std::string_view str, std::string_view delimiter ) noexcept;
377
388 [[nodiscard]] inline constexpr std::string_view extractBetween( std::string_view str, std::string_view start, std::string_view end ) noexcept;
389
398 [[nodiscard]] inline constexpr std::string_view removePrefix( std::string_view str, std::string_view prefix ) noexcept;
399
408 [[nodiscard]] inline constexpr std::string_view removeSuffix( std::string_view str, std::string_view suffix ) noexcept;
409
410 //----------------------------------------------
411 // Character & String Removal
412 //----------------------------------------------
413
422 [[nodiscard]] inline std::string removeAll( std::string_view str, char ch );
423
433 [[nodiscard]] inline std::string removeAll( std::string_view str, std::string_view substr );
434
444 template <typename Predicate>
445 [[nodiscard]] inline std::string removeIf( std::string_view str, Predicate pred );
446
455 [[nodiscard]] inline std::string removeWhitespace( std::string_view str );
456
466 [[nodiscard]] inline std::string collapseWhitespace( std::string_view str );
467
468 //----------------------------------------------
469 // String trimming
470 //----------------------------------------------
471
479 [[nodiscard]] inline constexpr std::string_view trimStart( std::string_view str ) noexcept;
480
488 [[nodiscard]] inline constexpr std::string_view trimEnd( std::string_view str ) noexcept;
489
497 [[nodiscard]] inline constexpr std::string_view trim( std::string_view str ) noexcept;
498
499 //----------------------------------------------
500 // Predicate-based operations
501 //----------------------------------------------
502
513 template <typename Predicate>
514 [[nodiscard]] inline constexpr std::string_view trimStartIf( std::string_view str, Predicate pred ) noexcept;
515
526 template <typename Predicate>
527 [[nodiscard]] inline constexpr std::string_view trimEndIf( std::string_view str, Predicate pred ) noexcept;
528
539 template <typename Predicate>
540 [[nodiscard]] inline constexpr std::string_view trimIf( std::string_view str, Predicate pred ) noexcept;
541
551 template <typename Predicate>
552 [[nodiscard]] inline constexpr std::size_t countIf( std::string_view str, Predicate pred ) noexcept;
553
563 template <typename Predicate>
564 [[nodiscard]] inline constexpr std::size_t findIf( std::string_view str, Predicate pred ) noexcept;
565
575 template <typename Predicate>
576 [[nodiscard]] inline constexpr std::size_t findIfNot( std::string_view str, Predicate pred ) noexcept;
577
589 template <typename Predicate>
590 [[nodiscard]] inline std::string replaceIf( std::string_view str, Predicate pred, char replacement );
591
592 //----------------------------------------------
593 // String case conversion
594 //----------------------------------------------
595
604 [[nodiscard]] inline std::string toLower( std::string_view str );
605
614 [[nodiscard]] inline std::string toUpper( std::string_view str );
615
616 //----------------------------------------------
617 // Character case conversion
618 //----------------------------------------------
619
627 [[nodiscard]] inline constexpr char toLower( char c ) noexcept;
628
636 [[nodiscard]] inline constexpr char toUpper( char c ) noexcept;
637
638 //----------------------------------------------
639 // String parsing
640 //----------------------------------------------
641
642 // Note: fromString<T> templates are defined in Utils.inl
643
644 //----------------------------------------------
645 // Network and URI validation
646 //----------------------------------------------
647
648 //-----------------------------
649 // URI character classification
650 //-----------------------------
651
658 [[nodiscard]] inline constexpr bool isUriReserved( char c ) noexcept;
659
667 [[nodiscard]] inline constexpr bool isUriReserved( std::string_view str ) noexcept;
668
675 [[nodiscard]] inline constexpr bool isUriUnreserved( char c ) noexcept;
676
684 [[nodiscard]] inline constexpr bool isUriUnreserved( std::string_view str ) noexcept;
685
686 //-----------------------------
687 // URL encoding/decoding
688 //-----------------------------
689
699 [[nodiscard]] inline std::string urlEncode( std::string_view str );
700
710 [[nodiscard]] inline std::string urlDecode( std::string_view str ) noexcept;
711
712 //-----------------------------
713 // JSON escape/unescape
714 //-----------------------------
715
725 [[nodiscard]] inline std::string jsonEscape( std::string_view str );
726
736 [[nodiscard]] inline std::string jsonUnescape( std::string_view str ) noexcept;
737
738 //-----------------------------
739 // XML/HTML escape/unescape
740 //-----------------------------
741
755 [[nodiscard]] inline std::string xmlEscape( std::string_view str );
756
767 [[nodiscard]] inline std::string xmlUnescape( std::string_view str ) noexcept;
768
769 //-----------------------------
770 // C/C++ escape sequences
771 //-----------------------------
772
785 [[nodiscard]] inline std::string cppEscape( std::string_view str );
786
798 [[nodiscard]] inline std::string cppUnescape( std::string_view str ) noexcept;
799
800 //-----------------------------
801 // String formatting utilities
802 //-----------------------------
803
813 [[nodiscard]] inline std::string truncate( std::string_view str, size_t maxLength );
814
826 [[nodiscard]] inline std::string truncate( std::string_view str, size_t maxLength, std::string_view ellipsis );
827
839 [[nodiscard]] inline std::string wordWrap( std::string_view str, size_t width );
840
851 [[nodiscard]] inline std::string indent( std::string_view str, size_t spaces );
852
862 [[nodiscard]] inline std::string dedent( std::string_view str );
863
864 //-----------------------------
865 // Advanced comparison
866 //-----------------------------
867
877 [[nodiscard]] inline constexpr int compareIgnoreCase( std::string_view lhs, std::string_view rhs ) noexcept;
878
889 [[nodiscard]] inline constexpr int naturalCompare( std::string_view lhs, std::string_view rhs ) noexcept;
890
900 [[nodiscard]] inline constexpr std::string_view commonPrefix( std::string_view lhs, std::string_view rhs ) noexcept;
901
911 [[nodiscard]] inline constexpr std::string_view commonSuffix( std::string_view lhs, std::string_view rhs ) noexcept;
912
913 //-----------------------------
914 // IP address validation
915 //-----------------------------
916
924 [[nodiscard]] inline constexpr bool isIpv4Address( std::string_view str ) noexcept;
925
933 [[nodiscard]] inline constexpr bool isIpv6Address( std::string_view str ) noexcept;
934
935 //-----------------------------
936 // Host validation
937 //-----------------------------
938
948 [[nodiscard]] inline constexpr bool isHostname( std::string_view str ) noexcept;
949
957 [[nodiscard]] inline constexpr bool isIdnHostname( std::string_view str ) noexcept;
958
967 [[nodiscard]] inline constexpr bool isDomainName( std::string_view str ) noexcept;
968
969 //-----------------------------
970 // Port validation
971 //-----------------------------
972
981 [[nodiscard]] inline constexpr bool isPortNumber( std::string_view str ) noexcept;
982
983 //-----------------------------
984 // Endpoint parsing
985 //-----------------------------
986
998 [[nodiscard]] inline bool tryParseEndpoint( std::string_view endpoint,
999 std::string_view& host,
1000 uint16_t& port ) noexcept;
1001
1002 //-----------------------------
1003 // Date and Time validation (RFC 3339)
1004 //-----------------------------
1005
1015 [[nodiscard]] inline constexpr bool isDateTime( std::string_view str ) noexcept;
1016
1025 [[nodiscard]] inline constexpr bool isDate( std::string_view str ) noexcept;
1026
1035 [[nodiscard]] inline constexpr bool isTime( std::string_view str ) noexcept;
1036
1045 [[nodiscard]] inline constexpr bool isDuration( std::string_view str ) noexcept;
1046
1047 //-----------------------------
1048 // Email validation (RFC 5321)
1049 //-----------------------------
1050
1060 [[nodiscard]] inline constexpr bool isEmail( std::string_view str ) noexcept;
1061
1069 [[nodiscard]] inline constexpr bool isIdnEmail( std::string_view str ) noexcept;
1070
1071 //-----------------------------
1072 // UUID validation (RFC 4122)
1073 //-----------------------------
1074
1083 [[nodiscard]] inline constexpr bool isUuid( std::string_view str ) noexcept;
1084
1085 //-----------------------------
1086 // URI validation (RFC 3986)
1087 //-----------------------------
1088
1097 [[nodiscard]] inline constexpr bool isUri( std::string_view str ) noexcept;
1098
1107 [[nodiscard]] inline constexpr bool isUriReference( std::string_view str ) noexcept;
1108
1119 [[nodiscard]] inline constexpr bool isUriTemplate( std::string_view str ) noexcept;
1120
1121 //-----------------------------
1122 // IRI validation (RFC 3987)
1123 //-----------------------------
1124
1133 [[nodiscard]] inline constexpr bool isIri( std::string_view str ) noexcept;
1134
1143 [[nodiscard]] inline constexpr bool isIriReference( std::string_view str ) noexcept;
1144
1145 //-----------------------------
1146 // JSON Pointer validation (RFC 6901)
1147 //-----------------------------
1148
1158 [[nodiscard]] inline constexpr bool isJsonPointer( std::string_view str ) noexcept;
1159
1168 [[nodiscard]] inline constexpr bool isRelativeJsonPointer( std::string_view str ) noexcept;
1169} // namespace nfx::string
1170
1171#include "nfx/detail/string/Utils.inl"
constexpr bool isAlphaNumeric(char c) noexcept
Check if character is ASCII alphanumeric.
std::string truncate(std::string_view str, size_t maxLength)
Truncate string to maximum length.
constexpr std::string_view substringAfter(std::string_view str, std::string_view delimiter) noexcept
Extract substring after first occurrence of delimiter.
std::string toLower(std::string_view str)
Convert string to lowercase.
constexpr std::string_view extractBetween(std::string_view str, std::string_view start, std::string_view end) noexcept
Extract substring between start and end delimiters.
std::string replaceAll(std::string_view str, std::string_view oldStr, std::string_view newStr)
Replace all occurrences of substring with replacement.
constexpr std::string_view removePrefix(std::string_view str, std::string_view prefix) noexcept
Remove prefix from string if present.
constexpr bool isIdnEmail(std::string_view str) noexcept
Validate Internationalized email address format (EAI/SMTPUTF8).
constexpr bool isIdnHostname(std::string_view str) noexcept
Validate Internationalized Domain Name (IDN) hostname format.
bool iequals(std::string_view lhs, std::string_view rhs) noexcept
Fast case-insensitive string comparison.
constexpr std::size_t lastIndexOf(std::string_view str, std::string_view substr) noexcept
Find last occurrence of substring.
std::string reverse(std::string_view str)
Reverse a string.
constexpr bool isNullOrWhiteSpace(std::string_view str) noexcept
Fast check if string is null, empty, or contains only whitespace.
std::string replaceIf(std::string_view str, Predicate pred, char replacement)
Replace characters matching predicate with replacement character.
constexpr bool isEmpty(std::string_view str) noexcept
Fast check if string is empty.
std::string jsonEscape(std::string_view str)
Escape string for use in JSON (RFC 8259).
std::string toUpper(std::string_view str)
Convert string to uppercase.
constexpr bool isDuration(std::string_view str) noexcept
Validate ISO 8601 duration format.
bool tryParseEndpoint(std::string_view endpoint, std::string_view &host, uint16_t &port) noexcept
Parse network endpoint into host and port.
constexpr bool isUuid(std::string_view str) noexcept
Validate UUID format (RFC 4122).
std::string repeat(std::string_view str, std::size_t count)
Repeat string specified number of times.
constexpr std::string_view substringAfterLast(std::string_view str, std::string_view delimiter) noexcept
Extract substring after last occurrence of delimiter.
std::string replace(std::string_view str, std::string_view oldStr, std::string_view newStr)
Replace first occurrence of substring with replacement.
constexpr bool equals(std::string_view lhs, std::string_view rhs) noexcept
Fast case-sensitive string comparison.
constexpr std::string_view trimStart(std::string_view str) noexcept
Remove leading whitespace from string.
constexpr bool isPortNumber(std::string_view str) noexcept
Validate port number string (RFC 6335).
constexpr bool isEmail(std::string_view str) noexcept
Validate email address format (RFC 5321).
constexpr bool isUriTemplate(std::string_view str) noexcept
Validate URI Template format (RFC 6570).
constexpr bool isTime(std::string_view str) noexcept
Validate RFC 3339 full-time format.
constexpr bool isUriReserved(char c) noexcept
Check if character is URI reserved (RFC 3986 Section 2.2).
constexpr std::string_view trimIf(std::string_view str, Predicate pred) noexcept
Remove leading and trailing characters matching predicate.
constexpr bool isAlpha(char c) noexcept
Check if character is ASCII alphabetic.
std::string join(const Container &elements, std::string_view delimiter)
Join container elements with delimiter.
constexpr bool hasExactLength(std::string_view str, std::size_t expectedLength) noexcept
Fast check if string has exact length.
std::string urlDecode(std::string_view str) noexcept
Decode percent-encoded URL string (RFC 3986).
constexpr bool isDomainName(std::string_view str) noexcept
Validate domain name format (RFC 1035).
constexpr bool isIriReference(std::string_view str) noexcept
Validate IRI-reference format (RFC 3987).
constexpr bool isUri(std::string_view str) noexcept
Validate URI format (RFC 3986).
constexpr std::size_t countIf(std::string_view str, Predicate pred) noexcept
Count characters matching predicate.
constexpr bool isRelativeJsonPointer(std::string_view str) noexcept
Validate relative JSON Pointer format.
constexpr std::string_view commonPrefix(std::string_view lhs, std::string_view rhs) noexcept
Find longest common prefix of two strings.
std::string removeAll(std::string_view str, char ch)
Remove all occurrences of a character from string.
constexpr std::size_t indexOf(std::string_view str, std::string_view substr) noexcept
Find first occurrence of substring.
std::string center(std::string_view str, std::size_t width, char fillChar=' ')
Center string within specified width.
std::string removeIf(std::string_view str, Predicate pred)
Remove all characters matching a predicate from string.
constexpr bool isDate(std::string_view str) noexcept
Validate RFC 3339 full-date format.
std::string cppEscape(std::string_view str)
Escape string for use as C/C++ string literal.
std::string cppUnescape(std::string_view str) noexcept
Unescape C/C++ string literal escape sequences.
std::string padLeft(std::string_view str, std::size_t width, char fillChar=' ')
Pad string on the left to reach specified width.
constexpr std::string_view trimEnd(std::string_view str) noexcept
Remove trailing whitespace from string.
std::size_t count(std::string_view str, std::string_view substr) noexcept
Count occurrences of substring in string.
constexpr std::size_t findIf(std::string_view str, Predicate pred) noexcept
Find first character matching predicate.
constexpr bool endsWith(std::string_view str, std::string_view suffix) noexcept
Fast check if string ends with suffix.
constexpr std::string_view trimStartIf(std::string_view str, Predicate pred) noexcept
Remove leading characters matching predicate.
std::string collapseWhitespace(std::string_view str)
Collapse consecutive whitespace characters to single space.
constexpr std::string_view commonSuffix(std::string_view lhs, std::string_view rhs) noexcept
Find longest common suffix of two strings.
std::string indent(std::string_view str, size_t spaces)
Add indentation to all lines.
std::string xmlEscape(std::string_view str)
Escape string for use in XML/HTML content.
constexpr std::string_view removeSuffix(std::string_view str, std::string_view suffix) noexcept
Remove suffix from string if present.
std::string urlEncode(std::string_view str)
Encode string for use in URLs (percent-encoding per RFC 3986).
std::size_t countOverlapping(std::string_view str, std::string_view substr) noexcept
Count overlapping occurrences of substring in string.
constexpr std::size_t findIfNot(std::string_view str, Predicate pred) noexcept
Find first character NOT matching predicate.
std::string jsonUnescape(std::string_view str) noexcept
Unescape JSON string literal (RFC 8259).
constexpr bool startsWith(std::string_view str, std::string_view prefix) noexcept
Fast check if string starts with prefix.
std::string xmlUnescape(std::string_view str) noexcept
Unescape XML/HTML entity references.
constexpr bool isIpv4Address(std::string_view str) noexcept
Validate IPv4 address format (RFC 791).
constexpr bool isDigit(char c) noexcept
Check if character is ASCII digit.
constexpr int compareIgnoreCase(std::string_view lhs, std::string_view rhs) noexcept
Case-insensitive three-way comparison.
std::string wordWrap(std::string_view str, size_t width)
Wrap text to specified width.
constexpr bool isIri(std::string_view str) noexcept
Validate IRI format (RFC 3987).
constexpr std::string_view trimEndIf(std::string_view str, Predicate pred) noexcept
Remove trailing characters matching predicate.
constexpr std::string_view substringBeforeLast(std::string_view str, std::string_view delimiter) noexcept
Extract substring before last occurrence of delimiter.
constexpr bool isDateTime(std::string_view str) noexcept
Validate RFC 3339 date-time format.
constexpr bool isWhitespace(char c) noexcept
Check if character is whitespace.
constexpr std::string_view substringBefore(std::string_view str, std::string_view delimiter) noexcept
Extract substring before first occurrence of delimiter.
constexpr bool isIpv6Address(std::string_view str) noexcept
Validate IPv6 address format (RFC 4291, RFC 5952).
constexpr bool isUriReference(std::string_view str) noexcept
Validate URI-reference format (RFC 3986).
constexpr bool isJsonPointer(std::string_view str) noexcept
Validate JSON Pointer format (RFC 6901).
constexpr bool contains(std::string_view str, std::string_view substr) noexcept
Fast check if string contains substring.
std::string dedent(std::string_view str)
Remove common leading whitespace from all lines.
constexpr int naturalCompare(std::string_view lhs, std::string_view rhs) noexcept
Natural sorting comparison (handles embedded numbers).
constexpr bool isAllDigits(std::string_view str) noexcept
Check if string contains only ASCII digits.
std::string removeWhitespace(std::string_view str)
Remove all whitespace characters from string.
constexpr bool isHostname(std::string_view str) noexcept
Validate hostname format (RFC 1123).
std::string padRight(std::string_view str, std::size_t width, char fillChar=' ')
Pad string on the right to reach specified width.
constexpr std::string_view trim(std::string_view str) noexcept
Remove leading and trailing whitespace from string.
constexpr bool isUriUnreserved(char c) noexcept
Check if character is URI unreserved (RFC 3986 Section 2.3).
constexpr bool isHexDigit(char c) noexcept
Check if character is ASCII hexadecimal digit.