8#ifndef HPP_ALIB_STRINGS_STRING
9#define HPP_ALIB_STRINGS_STRING 1
24 #pragma warning( push )
25 #pragma warning( disable : 4127 )
28namespace alib {
namespace strings {
61template<
typename TChar>
74 #if ALIB_DEBUG_STRINGS
75 void dbgCheck()
const;
179 template <
typename TCharArray>
197 template<
typename TCharArray>
199 operator TCharArray ()
const
215 template<
typename TCharArray>
217 operator TCharArray ()
const
231 template<
typename TAllocator,
typename TEnableIf=
typename TAllocator::ChainedAllocator>
237 std::is_same<std::nullptr_t,T>::value )
244 template <
typename T,
291 template<
typename TAllocator>
294 if( (
length= copy.length) == 0 )
300 auto* newBuf= allocator().template AllocArray<TChar>( copy.length);
301 copy.CopyTo( newBuf );
405 template <
typename TCheck= CHK>
410 if constexpr ( TCheck::value )
421 "Non checking and region out of range or empty" )
443 template <
typename TCheck= CHK>
447 if constexpr ( TCheck::value )
451 "Non checking version: Index out of range" )
465 template <
typename TCheck= CHK>
468 if constexpr ( TCheck::value )
487 template <
typename TCheck= CHK>
491 if constexpr ( TCheck::value )
578 template <
typename TCheck =
CHK,
584 if constexpr ( TCheck::value )
629 template <
typename TCheck =
CHK,
636 if (TCheck::value &&
IsNull() )
return rhs.
IsNull() ? 0 : -1;
637 if (TCheck::value && rhs.
IsNull() )
return +1;
640 if ( TCheck::value &&
length == 0 )
return rhs.
length == 0 ? 0 : -1;
641 if ( rhs.
length == 0 )
return +1;
652 return thisIsShorter ? -1 : 1;
679 template <
typename TCheck =
CHK,
686 if constexpr ( TCheck::value )
690 cmpSub.
buffer+= rhsRegionStart;
691 cmpSub.
length= rhsRegionLength;
729 template <
typename TCheck =
CHK,
738 if constexpr ( TCheck::value )
742 cmpSub.
buffer+= rhsRegionStart;
743 cmpSub.
length= rhsRegionLength;
746 return TString(
buffer + regionStart, regionLength ).CompareTo<
CHK, TSensitivity>( cmpSub );
775 template<
typename TCheck =
CHK,
781 if constexpr ( TCheck::value )
783 if ( pos < 0 || pos + needleLength >
length || needle.
IsNull () )
785 if ( needleLength == 0 )
791 "STRINGS",
"Non checking and index out of range" )
793 "STRINGS",
"Non checking and emtpy compare string" )
818 template<
typename TCheck =
CHK,
822 if constexpr ( TCheck::value )
832 "Non checking and needle longer than this string." )
834 "Non checking and emtpy needle given." )
852 template<
typename TCheck =
CHK,
856 if constexpr ( TCheck::value )
866 "Non checking and needle longer than this string." )
868 "Non checking and emtpy needle given." )
895 template <
typename TCheck= CHK>
900 if constexpr ( TCheck::value )
903 if ( startIdx < 0 ) startIdx= 0;
904 else if ( startIdx >=
length )
return -1;
910 "Non checking and index out of range" )
918 return result !=
nullptr ? result -
buffer
933 template <
typename TCheck= CHK>
938 if constexpr ( TCheck::value )
950 "STRINGS",
"Non checking and region out of range or empty" )
958 return result !=
nullptr ? result -
buffer
977 return result !=
nullptr ? result -
buffer
995 template <
typename TCheck= CHK>
999 if constexpr ( TCheck::value )
1002 if ( startIdx < 0 ) startIdx= 0;
1008 "STRINGS",
"Non checking and index out of range" )
1012 return result !=
nullptr ? result -
buffer
1033 template <
typename TCheck= CHK>
1038 if constexpr ( TCheck::value )
1041 if ( startIndex < 0 )
return -1;
1047 "STRINGS",
"Non checking and index out of range" )
1051 while( startIndex >= 0 &&
buffer[ startIndex ] != needle )
1089 typename TCheck =
CHK>
1092 if constexpr ( TCheck::value )
1094 if ( startIdx < 0 ) startIdx= 0;
1095 if ( startIdx >=
length )
return -1;
1100 "STRINGS",
"Non checking and illegal parameters" )
1110 return idx == -1 ? -1 : startIdx + idx;
1136 typename TCheck =
CHK>
1139 if constexpr ( TCheck::value )
1141 if ( startIdx < 0 )
return -1;
1147 "STRINGS",
"Non checking and illegal parameters" )
1177 template<
typename TCheck =
CHK,
1183 if constexpr ( TCheck::value )
1187 if ( startIdx < 0 ) startIdx= 0;
1188 endIdx= (std::min) (endIdx,
length - needle.
Length() + 1 );
1189 if ( startIdx >= endIdx )
return -1;
1200 "STRINGS",
"Non checking and illegal parameters" )
1224 template <
typename TCheck= CHK>
1231 if constexpr ( TCheck::value )
1234 if ( startIdx < 0 ) startIdx= 0;
1235 else if ( startIdx >=
length )
return startIdx;
1240 "STRINGS",
"Non checking and index out of range" )
1287 template <
typename TCheck= CHK>
1292 if constexpr ( TCheck::value )
1295 if ( startPos < 0 ) startPos= 0;
1296 else if ( startPos >=
length )
return 0;
1301 "STRINGS",
"Non checking and index out of range" )
1330 template <
typename TCheck= CHK>
1336 if constexpr ( TCheck::value )
1339 if ( startPos < 0 ) startPos= 0;
1340 else if ( startPos >=
length )
return 0;
1345 "STRINGS",
"Non checking and index out of range" )
1353 if( startPos <
Length() && *(
buffer + startPos) == omit )
1379 template<
typename TCheck =
CHK,
1388 if constexpr ( TCheck::value )
1390 if ( startPos < 0 ) startPos= 0;
1391 if ( startPos + nLen >
length )
return 0;
1396 "STRINGS",
"Non checking and illegal parameters" )
1402 startPos+= needle.
Length();
1428 template<
typename TCheck =
CHK,
1438 if constexpr ( TCheck::value )
1440 if ( startPos < 0 ) startPos= 0;
1441 if ( startPos + nLen >
length )
return 0;
1446 "STRINGS",
"Non checking and illegal parameters" )
1515 integer* newIdx=
nullptr )
const;
1531 return ParseInt( 0, numberFormat, newIdx );
1547 return ParseInt( 0,
nullptr, newIdx );
1566 return ParseInt( startIdx,
nullptr, newIdx );
1600 integer* newIdx=
nullptr )
const;
1616 return ParseDec( 0, numberFormat, newIdx );
1632 return ParseDec( 0,
nullptr, newIdx );
1651 return ParseDec( startIdx,
nullptr, newIdx );
1681 integer* newIdx=
nullptr )
const;
1698 return ParseBin( 0, numberFormat, newIdx );
1714 return ParseBin( 0,
nullptr, newIdx );
1733 return ParseBin( startIdx,
nullptr, newIdx );
1763 integer* newIdx=
nullptr )
const;
1780 return ParseHex( 0, numberFormat, newIdx );
1796 return ParseHex( 0,
nullptr, newIdx );
1815 return ParseHex( startIdx,
nullptr, newIdx );
1845 integer* newIdx=
nullptr )
const;
1862 return ParseOct( 0, numberFormat, newIdx );
1878 return ParseOct( 0,
nullptr, newIdx );
1897 return ParseOct( startIdx,
nullptr, newIdx );
1927 integer* newIdx=
nullptr )
const;
1943 return ParseFloat( 0, numberFormat, newIdx );
1978 return ParseFloat( startIdx,
nullptr, newIdx );
2011 template<
typename TAllocator>
2020 auto* newBuf= allocator().template AllocArray<TChar>( copy.
length );
2039 template<
typename TAllocator>
2064 if (regionStart >=
length)
2072 if (regionStart < 0 )
2074 regionLength+= regionStart;
2079 if ( regionLength < 0 )
2086 if ( regionLength > maxRegionLength )
2087 regionLength= maxRegionLength;
2090 return regionLength == 0;
2108 template<
typename TCharConstOrMutable>
2121 TCharConstOrMutable*
p;
2152 return p == other.
p;
2160 return !(*
this == other);
2267 return p <= other.
p;
2285 return p >= other.
p;
2369 template<lang::Case TSensitivity =lang::Case::Sensitive>
2408template<
typename TChar,
typename TCharArray>
bool operator== (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return lhs.
template Equals <CHK, lang::Case::Sensitive>(rhs); }
2409template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) )
operator== (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return rhs.
template Equals <CHK, lang::Case::Sensitive>(lhs); }
2410template<
typename TChar,
typename TCharArray>
bool operator!= (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return !lhs.
template Equals <CHK, lang::Case::Sensitive>(rhs); }
2411template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) ) operator!= (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return !rhs.
template Equals <CHK, lang::Case::Sensitive>(lhs); }
2413template<
typename TChar,
typename TCharArray>
bool operator< (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return lhs.
template CompareTo<CHK, lang::Case::Sensitive>(rhs) < 0; }
2414template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) ) operator< (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return rhs.
template CompareTo<CHK, lang::Case::Sensitive>(lhs) > 0; }
2415template<
typename TChar,
typename TCharArray>
bool operator<= (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return lhs.
template CompareTo<CHK, lang::Case::Sensitive>(rhs) <= 0; }
2416template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) ) operator<= (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return rhs.
template CompareTo<CHK, lang::Case::Sensitive>(lhs) >= 0; }
2417template<
typename TChar,
typename TCharArray>
bool operator> (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return lhs.
template CompareTo<CHK, lang::Case::Sensitive>(rhs) > 0; }
2418template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) ) operator> (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return rhs.
template CompareTo<CHK, lang::Case::Sensitive>(lhs) < 0; }
2419template<
typename TChar,
typename TCharArray>
bool operator>= (
const TString<TChar>& lhs,
const TCharArray& rhs) {
return lhs.
template CompareTo<CHK, lang::Case::Sensitive>(rhs) >= 0; }
2420template<
typename TChar,
typename TCharArray>
ATMP_T_IF(
bool, !
ATMP_ISOF(TCharArray, TString<TChar>) ) operator>= (
const TCharArray& lhs,
const TString<TChar>& rhs) {
return rhs.
template CompareTo<CHK, lang::Case::Sensitive>(lhs) <= 0; }
2476#if ALIB_DEBUG_STRINGS
2477 extern template ALIB_API void TString<nchar>::dbgCheck()
const;
2478 extern template ALIB_API void TString<wchar>::dbgCheck()
const;
2479 extern template ALIB_API void TString<xchar>::dbgCheck()
const;
2521template<>
struct TT_StringConstants<nchar> {
constexpr static NString EmptyString() {
return "" ; } };
2522template<>
struct TT_StringConstants<wchar> {
constexpr static WString EmptyString() {
return A_WCHAR(
""); } };
2523template<>
struct TT_StringConstants<xchar> {
constexpr static XString EmptyString() {
return A_XCHAR(
""); } };
2574#if defined(_MSC_VER)
2575 #pragma warning( pop )
TRandomAccessIterator & operator-=(integer n)
TRandomAccessIterator operator+(integer n) const
bool operator<=(TRandomAccessIterator other) const
TCharConstOrMutable & operator*() const
TCharConstOrMutable * p
The pointer into the buffer is all we store.
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE TRandomAccessIterator & operator++()
TCharConstOrMutable value_type
Implementation of std::iterator_traits.
bool operator<(TRandomAccessIterator other) const
TCharConstOrMutable & operator*()
bool operator>=(TRandomAccessIterator other) const
TRandomAccessIterator & operator+=(integer n)
bool operator!=(TRandomAccessIterator other) const
TCharConstOrMutable & reference
Implementation of std::iterator_traits.
std::random_access_iterator_tag iterator_category
Implementation of std::iterator_traits.
TCharConstOrMutable * pointer
Implementation of std::iterator_traits.
integer operator-(TRandomAccessIterator other) const
bool operator==(TRandomAccessIterator other) const
bool operator>(TRandomAccessIterator other) const
TRandomAccessIterator operator--(int)
TRandomAccessIterator & operator--()
integer difference_type
Implementation of std::iterator_traits.
TRandomAccessIterator operator++(int)
TCharConstOrMutable & operator[](integer n) const
TRandomAccessIterator(TCharConstOrMutable *start=nullptr)
TRandomAccessIterator operator-(integer n) const
integer IndexOf(const TString &needle, integer startIdx=0, integer endIdx=strings::MAX_LEN) const
ConstIterator cend() const
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE integer IndexOfOrLength(TChar needle, integer startIdx) const
constexpr bool IsNull() const
int CompareTo(const TString< TChar > &rhs) const
uint64_t ParseDec(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
ALIB_WARNINGS_RESTORE ConstReverseIterator rbegin() const
uint64_t ParseOct(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
integer IndexOf(TChar needle, integer startIdx=0) const
int64_t ParseInt(integer *newIdx) const
ConstReverseIterator crbegin() const
constexpr bool IsEmpty() const
double ParseFloat(integer startIdx, integer *newIdx) const
int CompareTo(const TString &rhs, integer rhsRegionStart, integer rhsRegionLength=MAX_LEN) const
TChar CharAt(integer idx) const
uint64_t ParseOct(integer *newIdx) const
integer IndexOfSegmentEnd(TChar opener, TChar closer, integer idx) const
double ParseFloat(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
void Allocate(TAllocator &allocator, const TString< TChar > ©)
constexpr bool IsNotEmpty() const
ConstReverseIterator rend() const
TRandomAccessIterator< const TChar > ConstIterator
uint64_t ParseDec(integer startIdx, integer *newIdx) const
ALIB_API uint64_t ParseHex(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
constexpr integer Length() const
integer IndexOfFirstDifference(const TString &needle, lang::Case sensitivity=lang::Case::Sensitive, integer startIdx=0) const
TChar CharAtStart() const
TChar operator[](integer idx) const
uint64_t ParseOct(integer startIdx, integer *newIdx) const
uint64_t ParseBin(integer startIdx, integer *newIdx) const
bool ContainsAt(const TString &needle, integer pos) const
constexpr bool IsNotNull() const
ALIB_API uint64_t ParseBin(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
integer CountChar(TChar needle, integer startPos=0) const
int64_t ParseInt(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
integer IndexOfAny(const TString &needles, integer startIdx=0) const
uint64_t ParseDec(integer *newIdx) const
constexpr TString(const TCharArray &src)
ConstIterator cbegin() const
TChar CharType
Expose template parameter TChar to the outer world.
integer CopyTo(TChar *dest) const
std::size_t Hashcode() const
std::size_t HashcodeIgnoreCase() const
int64_t ParseInt(integer startIdx, integer *newIdx) const
ALIB_API uint64_t ParseDec(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
TString(ConstIterator &start, ConstIterator &end)
integer CountChar(TChar needle, TChar omit, integer startPos) const
integer Count(const TString &needle, const TString &omit, integer startPos=0) const
std::reverse_iterator< ConstIterator > ConstReverseIterator
bool AdjustRegion(integer ®ionStart, integer ®ionLength) const
integer IndexOfOrLength(TChar needle) const
integer IndexOf(TChar needle, integer regionStart, integer regionLength) const
bool Equals(const TString< TChar > &rhs) const
ConstReverseIterator crend() const
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE ConstIterator end() const
uint64_t ParseHex(integer *newIdx) const
ALIB_API double ParseFloat(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
ALIB_API int64_t ParseInt(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
ALIB_API integer indexOfString(const TString &needle, integer startIdx, integer endIdx) const
void Free(TAllocator &allocator)
ConstIterator begin() const
ALIB_API uint64_t ParseOct(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
ALIB_WARNINGS_RESTORE integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
bool EndsWith(const TString &needle) const
int CompareTo(const TString &rhs, integer rhsRegionStart, integer rhsRegionLength, integer regionStart, integer regionLength=MAX_LEN) const
double ParseFloat(integer *newIdx) const
bool StartsWith(const TString &needle) const
constexpr TString() noexcept=default
Defaulted default constructor.
integer Count(const TString &needle, integer startPos=0) const
uint64_t ParseBin(integer *newIdx) const
TString(TAllocator &allocator, const TString< TChar > ©)
constexpr const TChar * Buffer() const
integer LastIndexOfAny(const TString &needles, integer startIdx=MAX_LEN) const
ALIB_API uint64_t ParseDecDigits(integer startIdx=0, integer *newIdx=nullptr) const
uint64_t ParseHex(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
integer WStringLength() const
uint64_t ParseBin(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
uint64_t ParseHex(integer startIdx, integer *newIdx) const
#define ATMP_ISOF( T, TBase)
#define ALIB_WARNINGS_RESTORE
#define ALIB_WARNINGS_IGNORE_DOCS
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
#define ALIB_STRING_DBG_CHK(instance)
#define ATMP_SELECT_IF_1TP(TParam, ...)
#define ATMP_T_IF(T, Cond)
integer IndexOfAnyExcluded(const TChar *haystack, integer haystackLength, const TChar *needles, integer needlesLength)
integer IndexOfFirstDifference(const TChar *haystack, integer haystackLength, const TChar *needle, integer needleLength, lang::Case sensitivity)
integer LastIndexOfAnyInclude(const TChar *haystack, integer startIdx, const TChar *needles, integer needlesLength)
@ ExplicitOnly
Allows explicit construction of objects from character array data.
@ Implicit
Allows implicit (and explicit) construction of objects from character array data.
const TChar * Search(const TChar *haystack, integer haystackLength, TChar needle)
int Compare(const TChar *lhs, const TChar *rhs, integer cmpLength)
void Copy(const TChar *src, integer length, TChar *dest)
integer IndexOfAnyIncluded(const TChar *haystack, integer haystackLength, const TChar *needles, integer needlesLength)
integer LastIndexOfAnyExclude(const TChar *haystack, integer startIdx, const TChar *needles, integer needlesLength)
bool Equal(TChar lhs, TRhs rhs)
@ ExplicitOnly
Allows explicit access of the character array data from mutable or constant objects.
@ MutableOnly
Allows explicit access of the character array data from mutable objects.
int CompareIgnoreCase(const TChar *lhs, const TChar *rhs, integer cmpLength)
Inclusion
Denotes how members of a set something should be taken into account.
@ Include
Chooses inclusion.
Case
Denotes upper and lower case character treatment.
bool operator==(const String &lhs, const String &rhs)
static constexpr integer MAX_LEN
The maximum length of an ALib string.
constexpr WString EMPTY_WSTRING
An empty string of the wide character type.
constexpr NString NULL_NSTRING
A nulled string of the narrow character type.
constexpr StrangeString EMPTY_STRANGE_STRING
An empty string of the strange character type.
constexpr StrangeString NULL_STRANGE_STRING
A nulled string of the strange character type.
characters::wchar wchar
Type alias in namespace alib.
constexpr XString EMPTY_XSTRING
An empty string of the complement character type.
constexpr WString NULL_WSTRING
A nulled string of the wide character type.
constexpr ComplementString EMPTY_COMPLEMENT_STRING
An empty string of the complement character type.
constexpr const String EMPTY_STRING
An empty string of the default character type.
characters::xchar xchar
Type alias in namespace alib.
constexpr NString EMPTY_NSTRING
An empty string of the narrow character type.
strings::TString< wchar > WString
Type alias in namespace alib.
constexpr ComplementString NULL_COMPLEMENT_STRING
A nulled string of the complement character type.
constexpr XString NULL_XSTRING
A nulled string of the complement character type.
characters::nchar nchar
Type alias in namespace alib.
constexpr String NULL_STRING
A nulled string of the default character type.
strings::TString< xchar > XString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
static constexpr ConstructionType Construction
static TString Construct(const TChar *array, integer length)
static constexpr String< TChar > EmptyString()