13e519524SHoward Hinnant //===------------------------ stdexcept.cpp -------------------------------===// 23e519524SHoward Hinnant // 35b08a8a4SHoward Hinnant // The LLVM Compiler Infrastructure 43e519524SHoward Hinnant // 53e519524SHoward Hinnant // This file is distributed under the University of Illinois Open Source 63e519524SHoward Hinnant // License. See LICENSE.TXT for details. 73e519524SHoward Hinnant // 83e519524SHoward Hinnant //===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant #include "stdexcept" 113e519524SHoward Hinnant #include "new" 123e519524SHoward Hinnant #include "string" 133e519524SHoward Hinnant #include <cstdlib> 143e519524SHoward Hinnant #include <cstring> 153e519524SHoward Hinnant #include <cstdint> 163e519524SHoward Hinnant #include <cstddef> 173e519524SHoward Hinnant #include "system_error" 183e519524SHoward Hinnant 193e519524SHoward Hinnant // Note: optimize for size 203e519524SHoward Hinnant 213e519524SHoward Hinnant #pragma GCC visibility push(hidden) 223e519524SHoward Hinnant 233e519524SHoward Hinnant namespace 243e519524SHoward Hinnant { 253e519524SHoward Hinnant 263e519524SHoward Hinnant class __libcpp_nmstr 273e519524SHoward Hinnant { 283e519524SHoward Hinnant private: 293e519524SHoward Hinnant const char* str_; 303e519524SHoward Hinnant 313e519524SHoward Hinnant typedef std::size_t unused_t; 323e519524SHoward Hinnant typedef std::int32_t count_t; 333e519524SHoward Hinnant 343e519524SHoward Hinnant static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 353e519524SHoward Hinnant sizeof(count_t)); 363e519524SHoward Hinnant 373e519524SHoward Hinnant count_t& count() const throw() {return (count_t&)(*(str_ - sizeof(count_t)));} 383e519524SHoward Hinnant public: 393e519524SHoward Hinnant explicit __libcpp_nmstr(const char* msg); 403e519524SHoward Hinnant __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 413e519524SHoward Hinnant __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 423e519524SHoward Hinnant ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 433e519524SHoward Hinnant const char* c_str() const throw() {return str_;} 443e519524SHoward Hinnant }; 453e519524SHoward Hinnant 463e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const char* msg) 473e519524SHoward Hinnant { 483e519524SHoward Hinnant std::size_t len = strlen(msg); 493e519524SHoward Hinnant str_ = new char[len + 1 + offset]; 503e519524SHoward Hinnant unused_t* c = (unused_t*)str_; 513e519524SHoward Hinnant c[0] = c[1] = len; 523e519524SHoward Hinnant str_ += offset; 533e519524SHoward Hinnant count() = 0; 543e519524SHoward Hinnant std::strcpy(const_cast<char*>(c_str()), msg); 553e519524SHoward Hinnant } 563e519524SHoward Hinnant 573e519524SHoward Hinnant inline 583e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 593e519524SHoward Hinnant : str_(s.str_) 603e519524SHoward Hinnant { 61*128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 623e519524SHoward Hinnant } 633e519524SHoward Hinnant 643e519524SHoward Hinnant __libcpp_nmstr& 653e519524SHoward Hinnant __libcpp_nmstr::operator=(const __libcpp_nmstr& s) 663e519524SHoward Hinnant { 673e519524SHoward Hinnant const char* p = str_; 683e519524SHoward Hinnant str_ = s.str_; 69*128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 70*128ba719SHoward Hinnant if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 713e519524SHoward Hinnant delete [] (p-offset); 723e519524SHoward Hinnant return *this; 733e519524SHoward Hinnant } 743e519524SHoward Hinnant 753e519524SHoward Hinnant inline 763e519524SHoward Hinnant __libcpp_nmstr::~__libcpp_nmstr() 773e519524SHoward Hinnant { 78*128ba719SHoward Hinnant if (__sync_add_and_fetch(&count(), -1) < 0) 793e519524SHoward Hinnant delete [] (str_ - offset); 803e519524SHoward Hinnant } 813e519524SHoward Hinnant 823e519524SHoward Hinnant } 833e519524SHoward Hinnant 843e519524SHoward Hinnant #pragma GCC visiblity pop 853e519524SHoward Hinnant 863e519524SHoward Hinnant namespace std // purposefully not using versioning namespace 873e519524SHoward Hinnant { 883e519524SHoward Hinnant 893e519524SHoward Hinnant logic_error::logic_error(const string& msg) 903e519524SHoward Hinnant { 913e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 923e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 933e519524SHoward Hinnant } 943e519524SHoward Hinnant 953e519524SHoward Hinnant logic_error::logic_error(const char* msg) 963e519524SHoward Hinnant { 973e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 983e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 993e519524SHoward Hinnant } 1003e519524SHoward Hinnant 1013e519524SHoward Hinnant logic_error::logic_error(const logic_error& le) throw() 1023e519524SHoward Hinnant { 1033e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1043e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1053e519524SHoward Hinnant } 1063e519524SHoward Hinnant 1073e519524SHoward Hinnant logic_error& 1083e519524SHoward Hinnant logic_error::operator=(const logic_error& le) throw() 1093e519524SHoward Hinnant { 1103e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1113e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1123e519524SHoward Hinnant s1 = s2; 1133e519524SHoward Hinnant return *this; 1143e519524SHoward Hinnant } 1153e519524SHoward Hinnant 1163e519524SHoward Hinnant logic_error::~logic_error() throw() 1173e519524SHoward Hinnant { 1183e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1193e519524SHoward Hinnant s.~__libcpp_nmstr(); 1203e519524SHoward Hinnant } 1213e519524SHoward Hinnant 1223e519524SHoward Hinnant const char* 1233e519524SHoward Hinnant logic_error::what() const throw() 1243e519524SHoward Hinnant { 1253e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1263e519524SHoward Hinnant return s.c_str(); 1273e519524SHoward Hinnant } 1283e519524SHoward Hinnant 1293e519524SHoward Hinnant runtime_error::runtime_error(const string& msg) 1303e519524SHoward Hinnant { 1313e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1323e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 1333e519524SHoward Hinnant } 1343e519524SHoward Hinnant 1353e519524SHoward Hinnant runtime_error::runtime_error(const char* msg) 1363e519524SHoward Hinnant { 1373e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1383e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1393e519524SHoward Hinnant } 1403e519524SHoward Hinnant 1413e519524SHoward Hinnant runtime_error::runtime_error(const runtime_error& le) throw() 1423e519524SHoward Hinnant { 1433e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1443e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1453e519524SHoward Hinnant } 1463e519524SHoward Hinnant 1473e519524SHoward Hinnant runtime_error& 1483e519524SHoward Hinnant runtime_error::operator=(const runtime_error& le) throw() 1493e519524SHoward Hinnant { 1503e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1513e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1523e519524SHoward Hinnant s1 = s2; 1533e519524SHoward Hinnant return *this; 1543e519524SHoward Hinnant } 1553e519524SHoward Hinnant 1563e519524SHoward Hinnant runtime_error::~runtime_error() throw() 1573e519524SHoward Hinnant { 1583e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1593e519524SHoward Hinnant s.~__libcpp_nmstr(); 1603e519524SHoward Hinnant } 1613e519524SHoward Hinnant 1623e519524SHoward Hinnant const char* 1633e519524SHoward Hinnant runtime_error::what() const throw() 1643e519524SHoward Hinnant { 1653e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1663e519524SHoward Hinnant return s.c_str(); 1673e519524SHoward Hinnant } 1683e519524SHoward Hinnant 1693e519524SHoward Hinnant domain_error::~domain_error() throw() {} 1703e519524SHoward Hinnant invalid_argument::~invalid_argument() throw() {} 1713e519524SHoward Hinnant length_error::~length_error() throw() {} 1723e519524SHoward Hinnant out_of_range::~out_of_range() throw() {} 1733e519524SHoward Hinnant 1743e519524SHoward Hinnant range_error::~range_error() throw() {} 1753e519524SHoward Hinnant overflow_error::~overflow_error() throw() {} 1763e519524SHoward Hinnant underflow_error::~underflow_error() throw() {} 1773e519524SHoward Hinnant 1783e519524SHoward Hinnant } // std 179