zoukankan      html  css  js  c++  java
  • c++标准库string文件

    // string standard header
    
    // Copyright (c) Microsoft Corporation.
    // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
    
    #pragma once
    #ifndef _STRING_
    #define _STRING_
    #include <yvals_core.h>
    #if _STL_COMPILER_PREPROCESSOR
    #include <xstring>
    // The <cctype> include below is to workaround many projects that assumed
    // <string> includes it. We workaround it instead of fixing all the upstream
    // projects because <cctype> is inexpensive. See VSO#663136.
    #include <cctype>
    
    #pragma pack(push, _CRT_PACKING)
    #pragma warning(push, _STL_WARNING_LEVEL)
    #pragma warning(disable : _STL_DISABLED_WARNINGS)
    _STL_DISABLE_CLANG_WARNINGS
    #pragma push_macro("new")
    #undef new
    
    _STD_BEGIN
    // FUNCTION TEMPLATE getline
    template <class _Elem, class _Traits, class _Alloc>
    basic_istream<_Elem, _Traits>& getline(basic_istream<_Elem, _Traits>&& _Istr,
        basic_string<_Elem, _Traits, _Alloc>& _Str,
        const _Elem _Delim) { // get characters into string, discard delimiter
        using _Myis = basic_istream<_Elem, _Traits>;
    
        typename _Myis::iostate _State = _Myis::goodbit;
        bool _Changed                  = false;
        const typename _Myis::sentry _Ok(_Istr, true);
    
        if (_Ok) { // state okay, extract characters
            _TRY_IO_BEGIN
            _Str.erase();
            const typename _Traits::int_type _Metadelim = _Traits::to_int_type(_Delim);
            typename _Traits::int_type _Meta            = _Istr.rdbuf()->sgetc();
    
            for (;; _Meta = _Istr.rdbuf()->snextc()) {
                if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit
                    _State |= _Myis::eofbit;
                    break;
                } else if (_Traits::eq_int_type(_Meta, _Metadelim)) { // got a delimiter, discard it and quit
                    _Changed = true;
                    _Istr.rdbuf()->sbumpc();
                    break;
                } else if (_Str.max_size() <= _Str.size()) { // string too large, quit
                    _State |= _Myis::failbit;
                    break;
                } else { // got a character, add it to string
                    _Str += _Traits::to_char_type(_Meta);
                    _Changed = true;
                }
            }
            _CATCH_IO_(_Myis, _Istr)
        }
    
        if (!_Changed) {
            _State |= _Myis::failbit;
        }
    
        _Istr.setstate(_State);
        return _Istr;
    }
    
    template <class _Elem, class _Traits, class _Alloc>
    basic_istream<_Elem, _Traits>& getline(basic_istream<_Elem, _Traits>&& _Istr,
        basic_string<_Elem, _Traits, _Alloc>& _Str) { // get characters into string, discard newline
        return getline(_Istr, _Str, _Istr.widen('
    '));
    }
    
    template <class _Elem, class _Traits, class _Alloc>
    basic_istream<_Elem, _Traits>& getline(basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str,
        const _Elem _Delim) { // get characters into string, discard delimiter
        return getline(_STD move(_Istr), _Str, _Delim);
    }
    
    template <class _Elem, class _Traits, class _Alloc>
    basic_istream<_Elem, _Traits>& getline(basic_istream<_Elem, _Traits>& _Istr,
        basic_string<_Elem, _Traits, _Alloc>& _Str) { // get characters into string, discard newline
        return getline(_STD move(_Istr), _Str, _Istr.widen('
    '));
    }
    
    
    // sto* NARROW CONVERSIONS
    inline int stoi(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert string to int
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref      = 0;
        const long _Ans = _CSTD strtol(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoi argument");
        }
    
        if (_Errno_ref == ERANGE || _Ans < INT_MIN || INT_MAX < _Ans) {
            _Xout_of_range("stoi argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return static_cast<int>(_Ans);
    }
    
    inline long stol(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert string to long
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref      = 0;
        const long _Ans = _CSTD strtol(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stol argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stol argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline unsigned long stoul(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert string to unsigned long
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref               = 0;
        const unsigned long _Ans = _CSTD strtoul(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoul argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoul argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline long long stoll(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert string to long long
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref           = 0;
        const long long _Ans = _CSTD strtoll(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoll argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoll argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline unsigned long long stoull(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert string to unsigned long long
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref                    = 0;
        const unsigned long long _Ans = _CSTD strtoull(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoull argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoull argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline float stof(const string& _Str, size_t* _Idx = nullptr) { // convert string to float
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref       = 0;
        const float _Ans = _CSTD strtof(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stof argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stof argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline double stod(const string& _Str, size_t* _Idx = nullptr) { // convert string to double
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref        = 0;
        const double _Ans = _CSTD strtod(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stod argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stod argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline long double stold(const string& _Str, size_t* _Idx = nullptr) { // convert string to long double
        int& _Errno_ref  = errno; // Nonzero cost, pay it once
        const char* _Ptr = _Str.c_str();
        char* _Eptr;
        _Errno_ref             = 0;
        const long double _Ans = _CSTD strtold(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stold argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stold argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    // sto* WIDE CONVERSIONS
    inline int stoi(const wstring& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert wstring to int
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref      = 0;
        const long _Ans = _CSTD wcstol(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoi argument");
        }
    
        if (_Errno_ref == ERANGE || _Ans < INT_MIN || INT_MAX < _Ans) {
            _Xout_of_range("stoi argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return static_cast<int>(_Ans);
    }
    
    inline long stol(const wstring& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert wstring to long
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref      = 0;
        const long _Ans = _CSTD wcstol(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stol argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stol argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline unsigned long stoul(const wstring& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert wstring to unsigned long
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref               = 0;
        const unsigned long _Ans = _CSTD wcstoul(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoul argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoul argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline long long stoll(const wstring& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert wstring to long long
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref           = 0;
        const long long _Ans = _CSTD wcstoll(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoll argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoll argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline unsigned long long stoull(const wstring& _Str, size_t* _Idx = nullptr, int _Base = 10) {
        // convert wstring to unsigned long long
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref                    = 0;
        const unsigned long long _Ans = _CSTD wcstoull(_Ptr, &_Eptr, _Base);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stoull argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stoull argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline float stof(const wstring& _Str, size_t* _Idx = nullptr) { // convert wstring to float
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref       = 0;
        const float _Ans = _CSTD wcstof(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stof argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stof argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline double stod(const wstring& _Str, size_t* _Idx = nullptr) { // convert wstring to double
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref        = 0;
        const double _Ans = _CSTD wcstod(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stod argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stod argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    inline long double stold(const wstring& _Str, size_t* _Idx = nullptr) { // convert wstring to long double
        int& _Errno_ref     = errno; // Nonzero cost, pay it once
        const wchar_t* _Ptr = _Str.c_str();
        wchar_t* _Eptr;
        _Errno_ref             = 0;
        const long double _Ans = _CSTD wcstold(_Ptr, &_Eptr);
    
        if (_Ptr == _Eptr) {
            _Xinvalid_argument("invalid stold argument");
        }
    
        if (_Errno_ref == ERANGE) {
            _Xout_of_range("stold argument out of range");
        }
    
        if (_Idx) {
            *_Idx = static_cast<size_t>(_Eptr - _Ptr);
        }
    
        return _Ans;
    }
    
    // HELPERS FOR to_string AND to_wstring
    template <class _Elem, class _UTy>
    _Elem* _UIntegral_to_buff(_Elem* _RNext, _UTy _UVal) { // format _UVal into buffer *ending at* _RNext
        static_assert(is_unsigned_v<_UTy>, "_UTy must be unsigned");
    
    #ifdef _WIN64
        auto _UVal_trunc = _UVal;
    #else // ^^^ _WIN64 ^^^ // vvv !_WIN64 vvv
    
        constexpr bool _Big_uty = sizeof(_UTy) > 4;
        if
            _CONSTEXPR_IF(_Big_uty) { // For 64-bit numbers, work in chunks to avoid 64-bit divisions.
                while (_UVal > 0xFFFFFFFFU) {
                    auto _UVal_chunk = static_cast<unsigned long>(_UVal % 1000000000);
                    _UVal /= 1000000000;
    
                    for (int _Idx = 0; _Idx != 9; ++_Idx) {
                        *--_RNext = static_cast<_Elem>('0' + _UVal_chunk % 10);
                        _UVal_chunk /= 10;
                    }
                }
            }
    
        auto _UVal_trunc = static_cast<unsigned long>(_UVal);
    #endif // _WIN64
    
        do {
            *--_RNext = static_cast<_Elem>('0' + _UVal_trunc % 10);
            _UVal_trunc /= 10;
        } while (_UVal_trunc != 0);
        return _RNext;
    }
    
    template <class _Elem, class _Ty>
    basic_string<_Elem> _Integral_to_string(const _Ty _Val) { // convert _Val to string
        static_assert(is_integral_v<_Ty>, "_Ty must be integral");
        using _UTy = make_unsigned_t<_Ty>;
        _Elem _Buff[21]; // can hold -2^63 and 2^64 - 1, plus NUL
        _Elem* const _Buff_end = _STD end(_Buff);
        _Elem* _RNext          = _Buff_end;
        const auto _UVal       = static_cast<_UTy>(_Val);
        if (_Val < 0) {
            _RNext    = _UIntegral_to_buff(_RNext, 0 - _UVal);
            *--_RNext = '-';
        } else {
            _RNext = _UIntegral_to_buff(_RNext, _UVal);
        }
    
        return basic_string<_Elem>(_RNext, _Buff_end);
    }
    
    // to_string NARROW CONVERSIONS
    _NODISCARD inline string to_string(int _Val) { // convert int to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(unsigned int _Val) { // convert unsigned int to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(long _Val) { // convert long to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(unsigned long _Val) { // convert unsigned long to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(long long _Val) { // convert long long to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(unsigned long long _Val) { // convert unsigned long long to string
        return _Integral_to_string<char>(_Val);
    }
    
    _NODISCARD inline string to_string(double _Val) { // convert double to string
        const auto _Len = static_cast<size_t>(_CSTD _scprintf("%f", _Val));
        string _Str(_Len, '');
        _CSTD sprintf_s(&_Str[0], _Len + 1, "%f", _Val);
        return _Str;
    }
    
    _NODISCARD inline string to_string(float _Val) { // convert float to string
        return _STD to_string(static_cast<double>(_Val));
    }
    
    _NODISCARD inline string to_string(long double _Val) { // convert long double to string
        return _STD to_string(static_cast<double>(_Val));
    }
    
    // to_wstring WIDE CONVERSIONS
    _NODISCARD inline wstring to_wstring(int _Val) { // convert int to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(unsigned int _Val) { // convert unsigned int to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(long _Val) { // convert long to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(unsigned long _Val) { // convert unsigned long to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(long long _Val) { // convert long long to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(unsigned long long _Val) { // convert unsigned long long to wstring
        return _Integral_to_string<wchar_t>(_Val);
    }
    
    _NODISCARD inline wstring to_wstring(double _Val) { // convert double to wstring
        const auto _Len = static_cast<size_t>(_CSTD _scwprintf(L"%f", _Val));
        wstring _Str(_Len, L'');
        _CSTD swprintf_s(&_Str[0], _Len + 1, L"%f", _Val);
        return _Str;
    }
    
    _NODISCARD inline wstring to_wstring(float _Val) { // convert float to wstring
        return _STD to_wstring(static_cast<double>(_Val));
    }
    
    _NODISCARD inline wstring to_wstring(long double _Val) { // convert long double to wstring
        return _STD to_wstring(static_cast<double>(_Val));
    }
    _STD_END
    
    #pragma pop_macro("new")
    _STL_RESTORE_CLANG_WARNINGS
    #pragma warning(pop)
    #pragma pack(pop)
    #endif // _STL_COMPILER_PREPROCESSOR
    #endif // _STRING_
    
    
  • 相关阅读:
    Jaeger Client Go 链路追踪|入门详解
    Go 中的 gRPC 入门详解
    【五分钟】001-数据结构概论
    【重榜?】.NET 6 Preview 1 开箱上手!带你尝试新版本更新!
    分布式链路追踪框架的基本实现原理
    【网摘】SQL练习题
    【数据库】E-R图向关系模型转换的规则
    6.0 《数据库系统概论》之关系数据库的规范化理论(数据依赖对表的影响[插入-删除-修改-冗余]、1NF-2NF-3NF-BCNF-4NF、函数依赖与多值依赖)
    【数据库】入门基础概念以及部分题目 记录 +答案+个人分析
    5.0 数据库完整性详解(PRIMARY KEY、REFERENCES、CHECK、CONSTRAINT、DOMAIN、TRIGGER)
  • 原文地址:https://www.cnblogs.com/coding365/p/12872394.html
Copyright © 2011-2022 走看看