34 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) 35 #error "Only <final/final.h> can be included directly." 58 #include <type_traits> 63 #include "final/ftypes.h" 72 using FStringList = std::vector<FString>;
83 using size_type = std::wstring::size_type;
84 using difference_type = std::wstring::difference_type;
85 using iterator = std::wstring::iterator;
86 using const_iterator = std::wstring::const_iterator;
87 using reference = std::wstring::reference;
88 using const_reference = std::wstring::const_reference;
95 FString (std::size_t,
const UniChar&);
99 #if __cplusplus >= 201703L 100 FString (
const std::wstring_view&);
105 #if __cplusplus >= 201703L 106 FString (
const std::string_view&);
123 auto operator << (
const UniChar&) ->
FString&;
124 auto operator << (
const wchar_t) ->
FString&;
125 auto operator << (
const char) ->
FString&;
126 template <
typename NumT
127 , std::enable_if_t< ( std::is_integral<NumT>::value
128 && ! std::is_same<NumT, bool>::value
129 && ! std::is_pointer<NumT>::value )
130 || ( std::is_floating_point<NumT>::value
131 && ! std::is_pointer<NumT>::value )
133 auto operator << (
const NumT) ->
FString&;
137 rhs.string.append(lhs.toWString());
141 friend inline auto operator >> (
const FString& lhs, std::wstring& rhs) ->
const FString&
143 rhs.append(lhs.toWString());
147 friend inline auto operator >> (
const FString& lhs, std::string& rhs) ->
const FString&
149 rhs.append(lhs.toString());
153 friend inline auto operator >> (
const FString& lhs,
wchar_t& rhs) ->
const FString&
155 rhs = ( ! lhs.isEmpty() ) ? lhs.string[0] : L
'\0';
159 friend inline auto operator >> (
const FString& lhs,
char& rhs) ->
const FString&
161 rhs = ( ! lhs.isEmpty() ) ?
char(uChar(lhs.string[0])) :
'\0';
165 friend inline auto operator >> (
const FString& lhs, sInt16& rhs) ->
const FString&
171 friend inline auto operator >> (
const FString& lhs, uInt16& rhs) ->
const FString&
173 rhs = lhs.toUShort();
177 friend inline auto operator >> (
const FString& lhs, sInt32& rhs) ->
const FString&
183 friend inline auto operator >> (
const FString& lhs, uInt32& rhs) ->
const FString&
189 friend inline auto operator >> (
const FString& lhs, sInt64& rhs) ->
const FString&
195 friend inline auto operator >> (
const FString& lhs, uInt64& rhs) ->
const FString&
201 friend inline auto operator >> (
const FString& lhs,
double& rhs) ->
const FString&
203 rhs = lhs.toDouble();
207 friend inline auto operator >> (
const FString& lhs,
float& rhs) ->
const FString&
213 template <
typename IndexT>
214 constexpr
auto operator [] (
const IndexT) -> reference;
215 template <
typename IndexT>
216 constexpr
auto operator [] (
const IndexT)
const -> const_reference;
217 explicit operator bool ()
const;
218 auto operator () ()
const ->
const FString&;
220 friend inline auto operator < (
const FString& lhs,
const FString& rhs) ->
bool 222 return lhs.string < rhs.string;
225 template <
typename CharT
226 , enable_if_char_ptr_t<CharT> =
nullptr>
227 friend inline auto operator < (
const FString& lhs,
const CharT& rhs) ->
bool 229 lhs.char_string = lhs.internal_toCharString(lhs.string);
230 return rhs ? lhs.char_string.compare(rhs) < 0 : lhs.char_string.compare(
"") < 0;
233 template <
typename CharT
234 , enable_if_char_array_t<CharT> =
nullptr>
235 friend inline auto operator < (
const FString& lhs,
const CharT& rhs) ->
bool 237 lhs.char_string = lhs.internal_toCharString(lhs.string);
238 return lhs.char_string.compare(rhs) < 0;
241 template <
typename CharT
242 , enable_if_wchar_ptr_t<CharT> =
nullptr>
243 friend inline auto operator < (
const FString& lhs,
const CharT& rhs) ->
bool 245 return rhs ? lhs.string.compare(rhs) < 0 : lhs.string.compare(L
"") < 0;
248 template <
typename CharT
249 , enable_if_wchar_array_t<CharT> =
nullptr>
250 friend inline auto operator < (
const FString& lhs,
const CharT& rhs) ->
bool 252 return lhs.string.compare(rhs) < 0;
255 friend inline auto operator <= (
const FString& lhs,
const FString& rhs) ->
bool 257 return lhs.string <= rhs.string;
260 template <
typename CharT
261 , enable_if_char_ptr_t<CharT> =
nullptr>
262 friend inline auto operator <= (
const FString& lhs,
const CharT& rhs) ->
bool 264 lhs.char_string = lhs.internal_toCharString(lhs.string);
265 return rhs ? lhs.char_string.compare(rhs) <= 0 : lhs.char_string.compare(
"") <= 0;
268 template <
typename CharT
269 , enable_if_char_array_t<CharT> =
nullptr>
270 friend inline auto operator <= (
const FString& lhs,
const CharT& rhs) ->
bool 272 lhs.char_string = lhs.internal_toCharString(lhs.string);
273 return lhs.char_string.compare(rhs) <= 0;
276 template <
typename CharT
277 , enable_if_wchar_ptr_t<CharT> =
nullptr>
278 friend inline auto operator <= (
const FString& lhs,
const CharT& rhs) ->
bool 280 return rhs ? lhs.string.compare(rhs) <= 0 : lhs.string.compare(L
"") <= 0;
283 template <
typename CharT
284 , enable_if_wchar_array_t<CharT> =
nullptr>
285 friend inline auto operator <= (
const FString& lhs,
const CharT& rhs) ->
bool 287 return lhs.string.compare(rhs) <= 0;
290 friend inline auto operator == (
const FString& lhs,
const FString& rhs) ->
bool 292 return lhs.string == rhs.string;
295 template <
typename CharT
296 , enable_if_char_ptr_t<CharT> =
nullptr>
297 friend inline auto operator == (
const FString& lhs,
const CharT& rhs) ->
bool 299 lhs.char_string = lhs.internal_toCharString(lhs.string);
300 return rhs ? lhs.char_string.compare(rhs) == 0 : lhs.char_string.compare(
"") == 0;
303 template <
typename CharT
304 , enable_if_char_array_t<CharT> =
nullptr>
305 friend inline auto operator == (
const FString& lhs,
const CharT& rhs) ->
bool 307 lhs.char_string = lhs.internal_toCharString(lhs.string);
308 return lhs.char_string.compare(rhs) == 0;
311 template <
typename CharT
312 , enable_if_wchar_ptr_t<CharT> =
nullptr>
313 friend inline auto operator == (
const FString& lhs,
const CharT& rhs) ->
bool 315 return rhs ? lhs.string.compare(rhs) == 0 : lhs.string.compare(L
"") == 0;
318 template <
typename CharT
319 , enable_if_wchar_array_t<CharT> =
nullptr>
320 friend inline auto operator == (
const FString& lhs,
const CharT& rhs) ->
bool 322 return lhs.string.compare(rhs) == 0;
325 friend inline auto operator != (
const FString& lhs,
const FString& rhs) ->
bool 327 return ! ( lhs == rhs );
330 template <
typename CharT
331 , enable_if_char_ptr_t<CharT> =
nullptr>
332 friend inline auto operator != (
const FString& lhs,
const CharT& rhs) ->
bool 334 lhs.char_string = lhs.internal_toCharString(lhs.string);
335 return rhs ? lhs.char_string.compare(rhs) != 0 : lhs.char_string.compare(
"") != 0;
338 template <
typename CharT
339 , enable_if_char_array_t<CharT> =
nullptr>
340 friend inline auto operator != (
const FString& lhs,
const CharT& rhs) ->
bool 342 lhs.char_string = lhs.internal_toCharString(lhs.string);
343 return lhs.char_string.compare(rhs) != 0;
346 template <
typename CharT
347 , enable_if_wchar_ptr_t<CharT> =
nullptr>
348 friend inline auto operator != (
const FString& lhs,
const CharT& rhs) ->
bool 350 return rhs ? lhs.string.compare(rhs) != 0 : lhs.string.compare(L
"") != 0;
353 template <
typename CharT
354 , enable_if_wchar_array_t<CharT> =
nullptr>
355 friend inline auto operator != (
const FString& lhs,
const CharT& rhs) ->
bool 357 return lhs.string.compare(rhs) != 0;
360 friend inline auto operator >= (
const FString& lhs,
const FString& rhs) ->
bool 362 return lhs.string >= rhs.string;
365 template <
typename CharT
366 , enable_if_char_ptr_t<CharT> =
nullptr>
367 friend inline auto operator >= (
const FString& lhs,
const CharT& rhs) ->
bool 369 lhs.char_string = lhs.internal_toCharString(lhs.string);
370 return rhs ? lhs.char_string.compare(rhs) >= 0 : lhs.char_string.compare(
"") >= 0;
373 template <
typename CharT
374 , enable_if_char_array_t<CharT> =
nullptr>
375 friend inline auto operator >= (
const FString& lhs,
const CharT& rhs) ->
bool 377 lhs.char_string = lhs.internal_toCharString(lhs.string);
378 return lhs.char_string.compare(rhs) >= 0;
381 template <
typename CharT
382 , enable_if_wchar_ptr_t<CharT> =
nullptr>
383 friend inline auto operator >= (
const FString& lhs,
const CharT& rhs) ->
bool 385 return rhs ? lhs.string.compare(rhs) >= 0 : lhs.string.compare(L
"") >= 0;
388 template <
typename CharT
389 , enable_if_wchar_array_t<CharT> =
nullptr>
390 friend inline auto operator >= (
const FString& lhs,
const CharT& rhs) ->
bool 392 return lhs.string.compare(rhs) >= 0;
395 friend inline auto operator > (
const FString& lhs,
const FString& rhs) ->
bool 397 return lhs.string > rhs.string;
400 template <
typename CharT
401 , enable_if_char_ptr_t<CharT> =
nullptr>
402 friend inline auto operator > (
const FString& lhs,
const CharT& rhs) ->
bool 404 lhs.char_string = lhs.internal_toCharString(lhs.string);
405 return rhs ? lhs.char_string.compare(rhs) > 0 : lhs.char_string.compare(
"") > 0;
408 template <
typename CharT
409 , enable_if_char_array_t<CharT> =
nullptr>
410 friend inline auto operator > (
const FString& lhs,
const CharT& rhs) ->
bool 412 lhs.char_string = lhs.internal_toCharString(lhs.string);
413 return lhs.char_string.compare(rhs) > 0;
416 template <
typename CharT
417 , enable_if_wchar_ptr_t<CharT> =
nullptr>
418 friend inline auto operator > (
const FString& lhs,
const CharT& rhs) ->
bool 420 return rhs ? lhs.string.compare(rhs) > 0 : lhs.string.compare(L
"") > 0;
423 template <
typename CharT
424 , enable_if_wchar_array_t<CharT> =
nullptr>
425 friend inline auto operator > (
const FString& lhs,
const CharT& rhs) ->
bool 427 return lhs.string.compare(rhs) > 0;
431 virtual auto getClassName()
const ->
FString;
434 auto isEmpty()
const noexcept -> bool;
437 auto getLength()
const noexcept -> std::size_t;
438 auto capacity()
const noexcept -> std::size_t;
440 auto begin() noexcept -> iterator;
441 auto end() noexcept -> iterator;
442 auto begin()
const -> const_iterator;
443 auto end()
const -> const_iterator;
444 auto cbegin()
const noexcept -> const_iterator;
445 auto cend()
const noexcept -> const_iterator;
446 auto front() -> reference;
447 auto back() -> reference;
448 auto front()
const -> const_reference;
449 auto back()
const -> const_reference;
451 template <
typename... Args>
455 auto wc_str()
const ->
const wchar_t*;
456 auto wc_str() ->
wchar_t*;
457 auto c_str()
const ->
const char*;
458 auto c_str() ->
char*;
459 auto toWString()
const -> std::wstring;
460 auto toString()
const -> std::string;
462 auto toLower()
const ->
FString;
463 auto toUpper()
const ->
FString;
465 auto toShort()
const -> sInt16;
466 auto toUShort()
const -> uInt16;
467 auto toInt()
const -> int;
468 auto toUInt()
const -> uInt;
469 auto toLong()
const -> long;
470 auto toULong()
const -> uLong;
471 auto toFloat()
const -> float;
472 auto toDouble()
const -> double;
478 auto left (std::size_t)
const ->
FString;
479 auto right (std::size_t)
const ->
FString;
480 auto mid (std::size_t, std::size_t)
const ->
FString;
482 auto split (
const FString&)
const -> FStringList;
485 template <
typename NumT>
487 auto setNumber (sInt64) ->
FString&;
488 auto setNumber (uInt64) ->
FString&;
491 template <
typename NumT>
492 auto setFormatedNumber (NumT,
FString&& = nl_langinfo(THOUSEP)) ->
FString&;
493 auto setFormatedNumber (sInt64,
FString = nl_langinfo(THOUSEP)) ->
FString&;
494 auto setFormatedNumber (uInt64,
FString = nl_langinfo(THOUSEP)) ->
FString&;
501 auto replaceControlCodes()
const ->
FString;
502 auto expandTabs (
int = 8)
const ->
FString;
503 auto removeDel()
const ->
FString;
504 auto removeBackspaces()
const ->
FString;
507 auto overwrite (
const FString&, std::size_t = 0) ->
const FString&;
509 auto remove (std::size_t, std::size_t) ->
const FString&;
510 auto includes (
const FString&)
const -> bool;
514 static constexpr
auto INPBUFFER = uInt(200);
515 static constexpr
auto MALFORMED_STRING =
static_cast<std::size_t
>(-1);
518 void internal_assign (std::wstring);
519 auto internal_toCharString (
const std::wstring&)
const -> std::string;
520 auto internal_toWideString (
const char[])
const -> std::wstring;
523 std::wstring
string{};
524 mutable std::string char_string{};
525 static wchar_t null_char;
526 static const wchar_t const_null_char;
531 const auto& tmp = s1.string + s2.string;
535 friend auto operator << (std::ostream& outstr,
const FString& s) -> std::ostream&
537 const auto& width = std::size_t(outstr.width());
539 if ( s.string.length() > 0 )
541 outstr << s.internal_toCharString(s.string);
543 else if ( width > 0 )
545 const std::string fill_str(width, outstr.fill());
552 friend auto operator >> (std::istream& instr,
FString& s) -> std::istream&
554 std::array<char, FString::INPBUFFER + 1> buf{};
555 instr.getline (buf.data(), FString::INPBUFFER);
556 auto wide_string = s.internal_toWideString(buf.data());
558 if ( ! wide_string.empty() )
560 s.internal_assign (std::move(wide_string));
566 friend auto operator << (std::wostream& outstr,
const FString& s) -> std::wostream&
568 const auto& width = std::size_t(outstr.width());
570 if ( s.string.length() > 0 )
574 else if ( width > 0 )
576 const std::wstring fill_str(width, outstr.fill());
583 friend auto operator >> (std::wistream& instr,
FString& s) -> std::wistream&
585 std::array<wchar_t, FString::INPBUFFER + 1> buf{};
586 instr.getline (buf.data(), FString::INPBUFFER);
587 std::wstring str(buf.data());
588 s.internal_assign (std::move(str));
593 friend struct std::hash<finalcut::
FString>;
598 auto FStringCaseCompare (const FString&, const FString&) -> int;
602 template <typename NumT
603 , std::enable_if_t< ( std::is_integral<NumT>::value
604 && ! std::is_same<NumT, bool>::value
605 && ! std::is_pointer<NumT>::value )
606 || ( std::is_floating_point<NumT>::value
607 && ! std::is_pointer<NumT>::value )
609 inline auto FString::operator << (const NumT val) -> FString&
611 const FString numstr(FString().setNumber(val));
612 string.append(numstr.string);
617 template <typename IndexT>
618 constexpr auto FString::operator [] (const IndexT pos) -> reference
620 if ( isNegative(pos) || pos > IndexT(
string.length()) )
621 throw std::out_of_range(
"");
623 if ( std::size_t(pos) ==
string.length() )
626 return string[std::size_t(pos)];
630 template <
typename IndexT>
631 constexpr
auto FString::operator [] (
const IndexT pos)
const -> const_reference
633 if ( isNegative(pos) || pos > IndexT(
string.length()) )
634 throw std::out_of_range(
"");
636 if ( std::size_t(pos) ==
string.length() )
637 return const_null_char;
639 return string[std::size_t(pos)];
643 inline auto FString::getClassName()
const ->
FString 644 {
return "FString"; }
647 inline auto FString::isEmpty()
const noexcept ->
bool 648 {
return string.empty(); }
651 inline auto FString::getLength()
const noexcept -> std::size_t
652 {
return string.length(); }
655 inline auto FString::capacity()
const noexcept -> std::size_t
656 {
return string.capacity(); }
659 inline auto FString::begin() noexcept -> iterator
660 {
return string.begin(); }
663 inline auto FString::end() noexcept -> iterator
664 {
return string.end(); }
667 inline auto FString::begin()
const -> const_iterator
668 {
return this->
string.begin(); }
671 inline auto FString::end()
const -> const_iterator
672 {
return this->
string.end(); }
675 inline auto FString::cbegin()
const noexcept -> const_iterator
676 {
return this->
string.cbegin(); }
679 inline auto FString::cend()
const noexcept -> const_iterator
680 {
return this->
string.cend(); }
683 inline auto FString::front() -> reference
685 assert ( ! isEmpty() );
686 return string.front();
690 inline auto FString::back() -> reference
692 assert( ! isEmpty() );
693 return string.back();
697 inline auto FString::front()
const -> const_reference
699 assert ( ! isEmpty() );
700 return string.front();
704 inline auto FString::back()
const -> const_reference
706 assert( ! isEmpty() );
707 return string.back();
711 template <
typename... Args>
712 inline auto FString::sprintf (
const FString& format, Args&&... args) ->
FString&
714 std::array<wchar_t, 4096> buf{};
716 if ( format.isEmpty() )
722 std::swprintf ( buf.data(), buf.size(), format.wc_str()
723 , std::forward<Args>(args)... );
724 return setString(buf.data());
728 template <
typename NumT>
729 inline auto FString::setNumber (NumT num,
int precision) ->
FString&
731 if ( std::is_floating_point<NumT>::value )
732 return setNumber (lDouble(num), precision);
734 if ( isNegative(num) )
735 return setNumber (sInt64(num));
737 return setNumber (uInt64(num));
741 template <
typename NumT>
742 inline auto FString::setFormatedNumber (NumT num,
FString&& separator) ->
FString&
744 if ( isNegative(num) )
745 return setFormatedNumber (sInt64(num), std::move(separator));
747 return setFormatedNumber (uInt64(num), std::move(separator));
751 inline void FString::internal_assign (std::wstring s)
764 return std::hash<std::wstring>{}(p.string);
Definition: class_template.cpp:25