diff options
Diffstat (limited to 'libcxx/src')
-rw-r--r-- | libcxx/src/ios.cpp | 55 | ||||
-rw-r--r-- | libcxx/src/string.cpp | 690 |
2 files changed, 690 insertions, 55 deletions
diff --git a/libcxx/src/ios.cpp b/libcxx/src/ios.cpp index 4d1261e3854..eb597bfbdfd 100644 --- a/libcxx/src/ios.cpp +++ b/libcxx/src/ios.cpp @@ -20,61 +20,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template class __basic_string_common<true>; - -template class basic_string<char>; -template class basic_string<wchar_t>; - -template enable_if<__is_forward_iterator<char const*>::value, void>::type - basic_string<char, char_traits<char>, allocator<char> > - ::__init<char const*>(char const*, char const*); - -template enable_if<__is_forward_iterator<wchar_t const*>::value, void>::type - basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > - ::__init<wchar_t const*>(wchar_t const*, wchar_t const*); - -template - enable_if<__is_forward_iterator<char*>::value, - basic_string<char, char_traits<char>, allocator<char> >&>::type - basic_string<char, char_traits<char>, allocator<char> >:: - append<char*>(char*, char*); - -template - enable_if<__is_forward_iterator<wchar_t*>::value, - basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >&>::type - basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >:: - append<wchar_t*>(wchar_t*, wchar_t*); - -template - enable_if<__is_forward_iterator<char const*>::value, - string::iterator>::type - string:: - insert<char const*>(string::const_iterator, char const*, char const*); - -template - enable_if<__is_forward_iterator<wchar_t const*>::value, - wstring::iterator>::type - wstring:: - insert<wchar_t const*>(wstring::const_iterator, wchar_t const*, wchar_t const*); - -template - enable_if<__is_input_iterator<char const*>::value, string&>::type - string:: - replace<char const*>(string::iterator, string::iterator, char const*, char const*); - -template - enable_if<__is_input_iterator<wchar_t const*>::value, wstring&>::type - wstring:: - replace<wchar_t const*>(wstring::iterator, wstring::iterator, wchar_t const*, wchar_t const*); - -template - enable_if<__is_forward_iterator<wchar_t*>::value, wstring&>::type - wstring::assign<wchar_t*>(wchar_t*, wchar_t*); - -template - string - operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); - template class basic_ios<char>; template class basic_ios<wchar_t>; diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp new file mode 100644 index 00000000000..819935c07d0 --- /dev/null +++ b/libcxx/src/string.cpp @@ -0,0 +1,690 @@ +//===------------------------- string.cpp ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "string" +#include "cstdlib" +#include "cwchar" +#include "cerrno" + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __basic_string_common<true>; + +template class basic_string<char>; +template class basic_string<wchar_t>; + +template enable_if<__is_forward_iterator<char const*>::value, void>::type + basic_string<char, char_traits<char>, allocator<char> > + ::__init<char const*>(char const*, char const*); + +template enable_if<__is_forward_iterator<wchar_t const*>::value, void>::type + basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > + ::__init<wchar_t const*>(wchar_t const*, wchar_t const*); + +template + enable_if<__is_forward_iterator<char*>::value, + basic_string<char, char_traits<char>, allocator<char> >&>::type + basic_string<char, char_traits<char>, allocator<char> >:: + append<char*>(char*, char*); + +template + enable_if<__is_forward_iterator<wchar_t*>::value, + basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >&>::type + basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >:: + append<wchar_t*>(wchar_t*, wchar_t*); + +template + enable_if<__is_forward_iterator<char const*>::value, + string::iterator>::type + string:: + insert<char const*>(string::const_iterator, char const*, char const*); + +template + enable_if<__is_forward_iterator<wchar_t const*>::value, + wstring::iterator>::type + wstring:: + insert<wchar_t const*>(wstring::const_iterator, wchar_t const*, wchar_t const*); + +template + enable_if<__is_input_iterator<char const*>::value, string&>::type + string:: + replace<char const*>(string::iterator, string::iterator, char const*, char const*); + +template + enable_if<__is_input_iterator<wchar_t const*>::value, wstring&>::type + wstring:: + replace<wchar_t const*>(wstring::iterator, wstring::iterator, wchar_t const*, wchar_t const*); + +template + enable_if<__is_forward_iterator<wchar_t*>::value, wstring&>::type + wstring::assign<wchar_t*>(wchar_t*, wchar_t*); + +template + string + operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); + +int +stoi(const string& str, size_t* idx, int base) +{ + char* ptr; + const char* const p = str.c_str(); + long r = strtol(p, &ptr, base); + if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) + ptr = const_cast<char*>(p); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoi: no conversion"); + throw out_of_range("stoi: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return static_cast<int>(r); +} + +int +stoi(const wstring& str, size_t* idx, int base) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + long r = wcstol(p, &ptr, base); + if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) + ptr = const_cast<wchar_t*>(p); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoi: no conversion"); + throw out_of_range("stoi: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return static_cast<int>(r); +} + +long +stol(const string& str, size_t* idx, int base) +{ + char* ptr; + const char* const p = str.c_str(); + long r = strtol(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stol: no conversion"); + throw out_of_range("stol: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +long +stol(const wstring& str, size_t* idx, int base) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + long r = wcstol(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stol: no conversion"); + throw out_of_range("stol: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +unsigned long +stoul(const string& str, size_t* idx, int base) +{ + char* ptr; + const char* const p = str.c_str(); + unsigned long r = strtoul(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoul: no conversion"); + throw out_of_range("stoul: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +unsigned long +stoul(const wstring& str, size_t* idx, int base) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + unsigned long r = wcstoul(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoul: no conversion"); + throw out_of_range("stoul: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +long long +stoll(const string& str, size_t* idx, int base) +{ + char* ptr; + const char* const p = str.c_str(); + long long r = strtoll(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoll: no conversion"); + throw out_of_range("stoll: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +long long +stoll(const wstring& str, size_t* idx, int base) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + long long r = wcstoll(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoll: no conversion"); + throw out_of_range("stoll: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +unsigned long long +stoull(const string& str, size_t* idx, int base) +{ + char* ptr; + const char* const p = str.c_str(); + unsigned long long r = strtoull(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoull: no conversion"); + throw out_of_range("stoull: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +unsigned long long +stoull(const wstring& str, size_t* idx, int base) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + unsigned long long r = wcstoull(p, &ptr, base); + if (ptr == p) + { + if (r == 0) + throw invalid_argument("stoull: no conversion"); + throw out_of_range("stoull: out of range"); + } + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +float +stof(const string& str, size_t* idx) +{ + char* ptr; + const char* const p = str.c_str(); + int errno_save = errno; + errno = 0; + double r = strtod(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stof: out of range"); + if (ptr == p) + throw invalid_argument("stof: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return static_cast<float>(r); +} + +float +stof(const wstring& str, size_t* idx) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + int errno_save = errno; + errno = 0; + double r = wcstod(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stof: out of range"); + if (ptr == p) + throw invalid_argument("stof: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return static_cast<float>(r); +} + +double +stod(const string& str, size_t* idx) +{ + char* ptr; + const char* const p = str.c_str(); + int errno_save = errno; + errno = 0; + double r = strtod(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stod: out of range"); + if (ptr == p) + throw invalid_argument("stod: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +double +stod(const wstring& str, size_t* idx) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + int errno_save = errno; + errno = 0; + double r = wcstod(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stod: out of range"); + if (ptr == p) + throw invalid_argument("stod: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +long double +stold(const string& str, size_t* idx) +{ + char* ptr; + const char* const p = str.c_str(); + int errno_save = errno; + errno = 0; + long double r = strtold(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stold: out of range"); + if (ptr == p) + throw invalid_argument("stold: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +long double +stold(const wstring& str, size_t* idx) +{ + wchar_t* ptr; + const wchar_t* const p = str.c_str(); + int errno_save = errno; + errno = 0; + long double r = wcstold(p, &ptr); + swap(errno, errno_save); + if (errno_save == ERANGE) + throw out_of_range("stold: out of range"); + if (ptr == p) + throw invalid_argument("stold: no conversion"); + if (idx) + *idx = static_cast<size_t>(ptr - p); + return r; +} + +string to_string(int val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%d", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(unsigned val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%u", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(long val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%ld", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(unsigned long val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%lu", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(long long val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%lld", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(unsigned long long val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%llu", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(float val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%f", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(double val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%f", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +string to_string(long double val) +{ + string s; + s.resize(s.capacity()); + while (true) + { + int n2 = snprintf(&s[0], s.size()+1, "%Lf", val); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return s; +} + +wstring to_wstring(int val) +{ + const size_t n = (numeric_limits<int>::digits / 3) + + ((numeric_limits<int>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%d", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(unsigned val) +{ + const size_t n = (numeric_limits<unsigned>::digits / 3) + + ((numeric_limits<unsigned>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%u", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(long val) +{ + const size_t n = (numeric_limits<long>::digits / 3) + + ((numeric_limits<long>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%ld", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(unsigned long val) +{ + const size_t n = (numeric_limits<unsigned long>::digits / 3) + + ((numeric_limits<unsigned long>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%lu", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(long long val) +{ + const size_t n = (numeric_limits<long long>::digits / 3) + + ((numeric_limits<long long>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%lld", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(unsigned long long val) +{ + const size_t n = (numeric_limits<unsigned long long>::digits / 3) + + ((numeric_limits<unsigned long long>::digits % 3) != 0) + + 1; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%llu", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(float val) +{ + const size_t n = 20; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%f", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(double val) +{ + const size_t n = 20; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%f", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +wstring to_wstring(long double val) +{ + const size_t n = 20; + wstring s(n, wchar_t()); + s.resize(s.capacity()); + while (true) + { + int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val); + if (n2 > 0) + { + s.resize(n2); + break; + } + s.resize(2*s.size()); + s.resize(s.capacity()); + } + return s; +} + +_LIBCPP_END_NAMESPACE_STD |