123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "mpt/base/pointer.hpp"
- #include "mpt/format/message.hpp"
- #include "mpt/format/simple_spec.hpp"
- #include "mpt/string/types.hpp"
- #include <stdexcept>
- #include "mptString.h"
- #include "openmpt/base/FlagSet.hpp"
- OPENMPT_NAMESPACE_BEGIN
- namespace mpt
- {
- #if MPT_USTRING_MODE_UTF8
- template <typename T> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::UTF8, x.ToUString())) { return mpt::ToCharset(mpt::Charset::UTF8, x.ToUString()); }
- #else
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- template <typename T> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::Locale, x.ToUString())) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUString()); }
- #else
- template <typename T> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::UTF8, x.ToUString())) { return mpt::ToCharset(mpt::Charset::UTF8, x.ToUString()); }
- #endif
- #endif
- inline std::string ToAString(const std::string & x) { return x; }
- inline std::string ToAString(const char * const & x) { return x; }
- std::string ToAString(const char &x) = delete;
- #if MPT_WSTRING_FORMAT
- std::string ToAString(const std::wstring & x) = delete;
- std::string ToAString(const wchar_t * const & x) = delete;
- std::string ToAString(const wchar_t &x ) = delete;
- #endif
- #if MPT_USTRING_MODE_UTF8
- std::string ToAString(const mpt::ustring & x) = delete;
- #endif
- #if defined(MPT_WITH_MFC)
- std::string ToAString(const CString & x) = delete;
- #endif
- std::string ToAString(const bool & x);
- std::string ToAString(const signed char & x);
- std::string ToAString(const unsigned char & x);
- std::string ToAString(const signed short & x);
- std::string ToAString(const unsigned short & x);
- std::string ToAString(const signed int & x);
- std::string ToAString(const unsigned int & x);
- std::string ToAString(const signed long & x);
- std::string ToAString(const unsigned long & x);
- std::string ToAString(const signed long long & x);
- std::string ToAString(const unsigned long long & x);
- std::string ToAString(const float & x);
- std::string ToAString(const double & x);
- std::string ToAString(const long double & x);
- template <typename T> auto ToUString(const T & x) -> decltype(x.ToUString()) { return x.ToUString(); }
- inline mpt::ustring ToUString(const mpt::ustring & x) { return x; }
- mpt::ustring ToUString(const std::string & x) = delete;
- mpt::ustring ToUString(const char * const & x) = delete;
- mpt::ustring ToUString(const char & x) = delete;
- #if MPT_WSTRING_FORMAT
- #if MPT_USTRING_MODE_UTF8
- mpt::ustring ToUString(const std::wstring & x);
- #endif
- mpt::ustring ToUString(const wchar_t * const & x);
- mpt::ustring ToUString(const wchar_t & x) = delete;
- #endif
- #if defined(MPT_WITH_MFC)
- mpt::ustring ToUString(const CString & x);
- #endif
- mpt::ustring ToUString(const bool & x);
- mpt::ustring ToUString(const signed char & x);
- mpt::ustring ToUString(const unsigned char & x);
- mpt::ustring ToUString(const signed short & x);
- mpt::ustring ToUString(const unsigned short & x);
- mpt::ustring ToUString(const signed int & x);
- mpt::ustring ToUString(const unsigned int & x);
- mpt::ustring ToUString(const signed long & x);
- mpt::ustring ToUString(const unsigned long & x);
- mpt::ustring ToUString(const signed long long & x);
- mpt::ustring ToUString(const unsigned long long & x);
- mpt::ustring ToUString(const float & x);
- mpt::ustring ToUString(const double & x);
- mpt::ustring ToUString(const long double & x);
- #if MPT_WSTRING_FORMAT
- std::wstring ToWString(const std::string & x) = delete;
- std::wstring ToWString(const char * const & x) = delete;
- std::wstring ToWString(const char & x) = delete;
- inline std::wstring ToWString(const std::wstring & x) { return x; }
- inline std::wstring ToWString(const wchar_t * const & x) { return x; }
- std::wstring ToWString(const wchar_t & x) = delete;
- #if MPT_USTRING_MODE_UTF8
- std::wstring ToWString(const mpt::ustring & x);
- #endif
- #if defined(MPT_WITH_MFC)
- std::wstring ToWString(const CString & x);
- #endif
- std::wstring ToWString(const bool & x);
- std::wstring ToWString(const signed char & x);
- std::wstring ToWString(const unsigned char & x);
- std::wstring ToWString(const signed short & x);
- std::wstring ToWString(const unsigned short & x);
- std::wstring ToWString(const signed int & x);
- std::wstring ToWString(const unsigned int & x);
- std::wstring ToWString(const signed long & x);
- std::wstring ToWString(const unsigned long & x);
- std::wstring ToWString(const signed long long & x);
- std::wstring ToWString(const unsigned long long & x);
- std::wstring ToWString(const float & x);
- std::wstring ToWString(const double & x);
- std::wstring ToWString(const long double & x);
- template <typename T> auto ToWString(const T & x) -> decltype(mpt::ToWide(x.ToUString())) { return mpt::ToWide(x.ToUString()); }
- #endif
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- template <typename T> struct ToLocaleHelper { mpt::lstring operator () (const T & v) { return mpt::ToLocale(ToUString(v)); } };
- template <> struct ToLocaleHelper<mpt::lstring> { mpt::lstring operator () (const mpt::lstring & v) { return v; } };
- #endif
- #if defined(MPT_WITH_MFC)
- template <typename T> struct ToCStringHelper { CString operator () (const T & v) { return mpt::ToCString(ToUString(v)); } };
- template <> struct ToCStringHelper<CString> { CString operator () (const CString & v) { return v; } };
- #endif
- template <typename Tstring> struct ToStringTFunctor {};
- template <> struct ToStringTFunctor<std::string> { template <typename T> inline std::string operator() (const T & x) { return ToAString(x); } };
- template <> struct ToStringTFunctor<mpt::ustring> { template <typename T> inline mpt::ustring operator() (const T & x) { return ToUString(x); } };
- #if MPT_WSTRING_FORMAT && MPT_USTRING_MODE_UTF8
- template <> struct ToStringTFunctor<std::wstring> { template <typename T> inline std::wstring operator() (const T & x) { return ToWString(x); } };
- #endif
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- template <> struct ToStringTFunctor<mpt::lstring> { template <typename T> inline mpt::lstring operator() (const T & x) { return mpt::ToLocaleHelper<T>()(x); } };
- #endif
- #if defined(MPT_WITH_MFC)
- template <> struct ToStringTFunctor<CString> { template <typename T> inline CString operator() (const T & x) { return mpt::ToCStringHelper<T>()(x); } };
- #endif
- template<typename Tstring, typename T> inline Tstring ToStringT(const T & x) { return ToStringTFunctor<Tstring>()(x); }
- struct ToStringFormatter {
- template <typename Tstring, typename T>
- static inline Tstring format(const T& value) {
- return ToStringTFunctor<Tstring>()(value);
- }
- };
- using FormatSpec = mpt::format_simple_spec;
- using FormatFlags = mpt::format_simple_flags;
- using fmt_base = mpt::format_simple_base;
- std::string FormatValA(const char & x, const FormatSpec & f) = delete;
- #if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
- std::string FormatValA(const wchar_t & x, const FormatSpec & f) = delete;
- #endif
- std::string FormatValA(const bool & x, const FormatSpec & f);
- std::string FormatValA(const signed char & x, const FormatSpec & f);
- std::string FormatValA(const unsigned char & x, const FormatSpec & f);
- std::string FormatValA(const signed short & x, const FormatSpec & f);
- std::string FormatValA(const unsigned short & x, const FormatSpec & f);
- std::string FormatValA(const signed int & x, const FormatSpec & f);
- std::string FormatValA(const unsigned int & x, const FormatSpec & f);
- std::string FormatValA(const signed long & x, const FormatSpec & f);
- std::string FormatValA(const unsigned long & x, const FormatSpec & f);
- std::string FormatValA(const signed long long & x, const FormatSpec & f);
- std::string FormatValA(const unsigned long long & x, const FormatSpec & f);
- std::string FormatValA(const float & x, const FormatSpec & f);
- std::string FormatValA(const double & x, const FormatSpec & f);
- std::string FormatValA(const long double & x, const FormatSpec & f);
- mpt::ustring FormatValU(const char & x, const FormatSpec & f) = delete;
- #if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
- mpt::ustring FormatValU(const wchar_t & x, const FormatSpec & f) = delete;
- #endif
- mpt::ustring FormatValU(const bool & x, const FormatSpec & f);
- mpt::ustring FormatValU(const signed char & x, const FormatSpec & f);
- mpt::ustring FormatValU(const unsigned char & x, const FormatSpec & f);
- mpt::ustring FormatValU(const signed short & x, const FormatSpec & f);
- mpt::ustring FormatValU(const unsigned short & x, const FormatSpec & f);
- mpt::ustring FormatValU(const signed int & x, const FormatSpec & f);
- mpt::ustring FormatValU(const unsigned int & x, const FormatSpec & f);
- mpt::ustring FormatValU(const signed long & x, const FormatSpec & f);
- mpt::ustring FormatValU(const unsigned long & x, const FormatSpec & f);
- mpt::ustring FormatValU(const signed long long & x, const FormatSpec & f);
- mpt::ustring FormatValU(const unsigned long long & x, const FormatSpec & f);
- mpt::ustring FormatValU(const float & x, const FormatSpec & f);
- mpt::ustring FormatValU(const double & x, const FormatSpec & f);
- mpt::ustring FormatValU(const long double & x, const FormatSpec & f);
- #if MPT_WSTRING_FORMAT
- std::wstring FormatValW(const char & x, const FormatSpec & f) = delete;
- #if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
- std::wstring FormatValW(const wchar_t & x, const FormatSpec & f) = delete;
- #endif
- std::wstring FormatValW(const bool & x, const FormatSpec & f);
- std::wstring FormatValW(const signed char & x, const FormatSpec & f);
- std::wstring FormatValW(const unsigned char & x, const FormatSpec & f);
- std::wstring FormatValW(const signed short & x, const FormatSpec & f);
- std::wstring FormatValW(const unsigned short & x, const FormatSpec & f);
- std::wstring FormatValW(const signed int & x, const FormatSpec & f);
- std::wstring FormatValW(const unsigned int & x, const FormatSpec & f);
- std::wstring FormatValW(const signed long & x, const FormatSpec & f);
- std::wstring FormatValW(const unsigned long & x, const FormatSpec & f);
- std::wstring FormatValW(const signed long long & x, const FormatSpec & f);
- std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f);
- std::wstring FormatValW(const float & x, const FormatSpec & f);
- std::wstring FormatValW(const double & x, const FormatSpec & f);
- std::wstring FormatValW(const long double & x, const FormatSpec & f);
- #endif
- template <typename Tstring> struct FormatValTFunctor {};
- template <> struct FormatValTFunctor<std::string> { template <typename T> inline std::string operator() (const T & x, const FormatSpec & f) { return FormatValA(x, f); } };
- template <> struct FormatValTFunctor<mpt::ustring> { template <typename T> inline mpt::ustring operator() (const T & x, const FormatSpec & f) { return FormatValU(x, f); } };
- #if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_FORMAT
- template <> struct FormatValTFunctor<std::wstring> { template <typename T> inline std::wstring operator() (const T & x, const FormatSpec & f) { return FormatValW(x, f); } };
- #endif
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- template <> struct FormatValTFunctor<mpt::lstring> { template <typename T> inline mpt::lstring operator() (const T & x, const FormatSpec & f) { return mpt::ToLocale(mpt::Charset::Locale, FormatValA(x, f)); } };
- #endif
- #if defined(MPT_WITH_MFC)
- #ifdef UNICODE
- template <> struct FormatValTFunctor<CString> { template <typename T> inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(FormatValW(x, f)); } };
- #else
- template <> struct FormatValTFunctor<CString> { template <typename T> inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(mpt::Charset::Locale, FormatValA(x, f)); } };
- #endif
- #endif
- template <typename Tstring>
- struct fmtT : fmt_base
- {
- template<typename T>
- static inline Tstring val(const T& x)
- {
- return ToStringTFunctor<Tstring>()(x);
- }
- template<typename T>
- static inline Tstring fmt(const T& x, const FormatSpec& f)
- {
- return FormatValTFunctor<Tstring>()(x, f);
- }
- template<typename T>
- static inline Tstring dec(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillOff());
- }
- template<int width, typename T>
- static inline Tstring dec0(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillNul().Width(width));
- }
- template<typename T>
- static inline Tstring dec(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillOff().Group(g).GroupSep(s));
- }
- template<int width, typename T>
- static inline Tstring dec0(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillNul().Width(width).Group(g).GroupSep(s));
- }
- template<typename T>
- static inline Tstring hex(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillOff());
- }
- template<typename T>
- static inline Tstring HEX(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillOff());
- }
- template<int width, typename T>
- static inline Tstring hex0(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillNul().Width(width));
- }
- template<int width, typename T>
- static inline Tstring HEX0(const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillNul().Width(width));
- }
- template<typename T>
- static inline Tstring hex(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillOff().Group(g).GroupSep(s));
- }
- template<typename T>
- static inline Tstring HEX(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillOff().Group(g).GroupSep(s));
- }
- template<int width, typename T>
- static inline Tstring hex0(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillNul().Width(width).Group(g).GroupSep(s));
- }
- template<int width, typename T>
- static inline Tstring HEX0(unsigned int g, char s, const T& x)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillNul().Width(width).Group(g).GroupSep(s));
- }
- template<typename T>
- static inline Tstring flt(const T& x, int precision = -1)
- {
- static_assert(std::is_floating_point<T>::value);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaNrm().FillOff().Precision(precision));
- }
- template<typename T>
- static inline Tstring fix(const T& x, int precision = -1)
- {
- static_assert(std::is_floating_point<T>::value);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaFix().FillOff().Precision(precision));
- }
- template<typename T>
- static inline Tstring sci(const T& x, int precision = -1)
- {
- static_assert(std::is_floating_point<T>::value);
- return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaSci().FillOff().Precision(precision));
- }
- template<typename T>
- static inline Tstring ptr(const T& x)
- {
- static_assert(std::is_pointer<T>::value || std::is_same<T, std::uintptr_t>::value || std::is_same<T, std::intptr_t>::value, "");
- return hex0<mpt::pointer_size * 2>(mpt::pointer_cast<const std::uintptr_t>(x));
- }
- template<typename T>
- static inline Tstring PTR(const T& x)
- {
- static_assert(std::is_pointer<T>::value || std::is_same<T, std::uintptr_t>::value || std::is_same<T, std::intptr_t>::value, "");
- return HEX0<mpt::pointer_size * 2>(mpt::pointer_cast<const std::uintptr_t>(x));
- }
- static inline Tstring pad_left(std::size_t width_, const Tstring &str)
- {
- typedef mpt::string_traits<Tstring> traits;
- typename traits::size_type width = static_cast<typename traits::size_type>(width_);
- return traits::pad(str, width, 0);
- }
- static inline Tstring pad_right(std::size_t width_, const Tstring &str)
- {
- typedef mpt::string_traits<Tstring> traits;
- typename traits::size_type width = static_cast<typename traits::size_type>(width_);
- return traits::pad(str, 0, width);
- }
- static inline Tstring left(std::size_t width_, const Tstring &str)
- {
- typedef mpt::string_traits<Tstring> traits;
- typename traits::size_type width = static_cast<typename traits::size_type>(width_);
- return (traits::length(str) < width) ? traits::pad(str, 0, width - traits::length(str)) : str;
- }
- static inline Tstring right(std::size_t width_, const Tstring &str)
- {
- typedef mpt::string_traits<Tstring> traits;
- typename traits::size_type width = static_cast<typename traits::size_type>(width_);
- return (traits::length(str) < width) ? traits::pad(str, width - traits::length(str), 0) : str;
- }
- static inline Tstring center(std::size_t width_, const Tstring &str)
- {
- typedef mpt::string_traits<Tstring> traits;
- typename traits::size_type width = static_cast<typename traits::size_type>(width_);
- return (traits::length(str) < width) ? traits::pad(str, (width - traits::length(str)) / 2, (width - traits::length(str) + 1) / 2) : str;
- }
- };
- typedef fmtT<std::string> afmt;
- #if MPT_WSTRING_FORMAT
- typedef fmtT<std::wstring> wfmt;
- #endif
- #if MPT_USTRING_MODE_WIDE
- typedef fmtT<std::wstring> ufmt;
- #else
- typedef fmtT<mpt::ustring> ufmt;
- #endif
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- typedef fmtT<mpt::lstring> lfmt;
- #endif
- #if MPT_OS_WINDOWS
- typedef fmtT<mpt::tstring> tfmt;
- #endif
- #if defined(MPT_WITH_MFC)
- typedef fmtT<CString> cfmt;
- #endif
- #define MPT_AFORMAT(f) mpt::format_message<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(f)>(f)
- #if MPT_WSTRING_FORMAT
- #define MPT_WFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count( L ## f ), std::wstring>( L ## f )
- #endif
- #define MPT_UFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(MPT_ULITERAL(f)), mpt::ustring>(MPT_ULITERAL(f))
- #if defined(MPT_ENABLE_CHARSET_LOCALE)
- #define MPT_LFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(f), mpt::lstring>(f)
- #endif
- #if MPT_OS_WINDOWS
- #define MPT_TFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(TEXT(f)), mpt::tstring>(TEXT(f))
- #endif
- #if defined(MPT_WITH_MFC)
- #define MPT_CFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(TEXT(f)), CString>(TEXT(f))
- #endif
- }
- namespace mpt { namespace String {
- template<typename T>
- mpt::ustring Combine(const std::vector<T> &vals, const mpt::ustring &sep=U_(","))
- {
- mpt::ustring str;
- for(std::size_t i = 0; i < vals.size(); ++i)
- {
- if(i > 0)
- {
- str += sep;
- }
- str += mpt::ufmt::val(vals[i]);
- }
- return str;
- }
- template<typename T>
- std::string Combine(const std::vector<T> &vals, const std::string &sep=std::string(","))
- {
- std::string str;
- for(std::size_t i = 0; i < vals.size(); ++i)
- {
- if(i > 0)
- {
- str += sep;
- }
- str += mpt::afmt::val(vals[i]);
- }
- return str;
- }
- } }
- template <typename enum_t, typename store_t>
- mpt::ustring ToUString(FlagSet<enum_t, store_t> flagset)
- {
- mpt::ustring str(flagset.size_bits(), UC_('0'));
- for(std::size_t x = 0; x < flagset.size_bits(); ++x)
- {
- str[flagset.size_bits() - x - 1] = (flagset.value().as_bits() & (static_cast<typename FlagSet<enum_t>::store_type>(1) << x) ? UC_('1') : UC_('0'));
- }
- return str;
- }
- OPENMPT_NAMESPACE_END
|