13e519524SHoward Hinnant //===------------------------ stdexcept.cpp -------------------------------===// 23e519524SHoward Hinnant // 3*5b08a8a4SHoward 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 #include <libkern/OSAtomic.h> 193e519524SHoward Hinnant 203e519524SHoward Hinnant // Note: optimize for size 213e519524SHoward Hinnant 223e519524SHoward Hinnant #pragma GCC visibility push(hidden) 233e519524SHoward Hinnant 243e519524SHoward Hinnant namespace 253e519524SHoward Hinnant { 263e519524SHoward Hinnant 273e519524SHoward Hinnant class __libcpp_nmstr 283e519524SHoward Hinnant { 293e519524SHoward Hinnant private: 303e519524SHoward Hinnant const char* str_; 313e519524SHoward Hinnant 323e519524SHoward Hinnant typedef std::size_t unused_t; 333e519524SHoward Hinnant typedef std::int32_t count_t; 343e519524SHoward Hinnant 353e519524SHoward Hinnant static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 363e519524SHoward Hinnant sizeof(count_t)); 373e519524SHoward Hinnant 383e519524SHoward Hinnant count_t& count() const throw() {return (count_t&)(*(str_ - sizeof(count_t)));} 393e519524SHoward Hinnant public: 403e519524SHoward Hinnant explicit __libcpp_nmstr(const char* msg); 413e519524SHoward Hinnant __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 423e519524SHoward Hinnant __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 433e519524SHoward Hinnant ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 443e519524SHoward Hinnant const char* c_str() const throw() {return str_;} 453e519524SHoward Hinnant }; 463e519524SHoward Hinnant 473e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const char* msg) 483e519524SHoward Hinnant { 493e519524SHoward Hinnant std::size_t len = strlen(msg); 503e519524SHoward Hinnant str_ = new char[len + 1 + offset]; 513e519524SHoward Hinnant unused_t* c = (unused_t*)str_; 523e519524SHoward Hinnant c[0] = c[1] = len; 533e519524SHoward Hinnant str_ += offset; 543e519524SHoward Hinnant count() = 0; 553e519524SHoward Hinnant std::strcpy(const_cast<char*>(c_str()), msg); 563e519524SHoward Hinnant } 573e519524SHoward Hinnant 583e519524SHoward Hinnant inline 593e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 603e519524SHoward Hinnant : str_(s.str_) 613e519524SHoward Hinnant { 623e519524SHoward Hinnant OSAtomicIncrement32Barrier(&count()); 633e519524SHoward Hinnant } 643e519524SHoward Hinnant 653e519524SHoward Hinnant __libcpp_nmstr& 663e519524SHoward Hinnant __libcpp_nmstr::operator=(const __libcpp_nmstr& s) 673e519524SHoward Hinnant { 683e519524SHoward Hinnant const char* p = str_; 693e519524SHoward Hinnant str_ = s.str_; 703e519524SHoward Hinnant OSAtomicIncrement32Barrier(&count()); 713e519524SHoward Hinnant if (OSAtomicDecrement32((count_t*)(p-sizeof(count_t))) < 0) 723e519524SHoward Hinnant delete [] (p-offset); 733e519524SHoward Hinnant return *this; 743e519524SHoward Hinnant } 753e519524SHoward Hinnant 763e519524SHoward Hinnant inline 773e519524SHoward Hinnant __libcpp_nmstr::~__libcpp_nmstr() 783e519524SHoward Hinnant { 793e519524SHoward Hinnant if (OSAtomicDecrement32(&count()) < 0) 803e519524SHoward Hinnant delete [] (str_ - offset); 813e519524SHoward Hinnant } 823e519524SHoward Hinnant 833e519524SHoward Hinnant } 843e519524SHoward Hinnant 853e519524SHoward Hinnant #pragma GCC visiblity pop 863e519524SHoward Hinnant 873e519524SHoward Hinnant namespace std // purposefully not using versioning namespace 883e519524SHoward Hinnant { 893e519524SHoward Hinnant 903e519524SHoward Hinnant logic_error::logic_error(const string& msg) 913e519524SHoward Hinnant { 923e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 933e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 943e519524SHoward Hinnant } 953e519524SHoward Hinnant 963e519524SHoward Hinnant logic_error::logic_error(const char* msg) 973e519524SHoward Hinnant { 983e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 993e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1003e519524SHoward Hinnant } 1013e519524SHoward Hinnant 1023e519524SHoward Hinnant logic_error::logic_error(const logic_error& le) throw() 1033e519524SHoward Hinnant { 1043e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1053e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1063e519524SHoward Hinnant } 1073e519524SHoward Hinnant 1083e519524SHoward Hinnant logic_error& 1093e519524SHoward Hinnant logic_error::operator=(const logic_error& le) throw() 1103e519524SHoward Hinnant { 1113e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1123e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1133e519524SHoward Hinnant s1 = s2; 1143e519524SHoward Hinnant return *this; 1153e519524SHoward Hinnant } 1163e519524SHoward Hinnant 1173e519524SHoward Hinnant logic_error::~logic_error() throw() 1183e519524SHoward Hinnant { 1193e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1203e519524SHoward Hinnant s.~__libcpp_nmstr(); 1213e519524SHoward Hinnant } 1223e519524SHoward Hinnant 1233e519524SHoward Hinnant const char* 1243e519524SHoward Hinnant logic_error::what() const throw() 1253e519524SHoward Hinnant { 1263e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1273e519524SHoward Hinnant return s.c_str(); 1283e519524SHoward Hinnant } 1293e519524SHoward Hinnant 1303e519524SHoward Hinnant runtime_error::runtime_error(const string& msg) 1313e519524SHoward Hinnant { 1323e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1333e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 1343e519524SHoward Hinnant } 1353e519524SHoward Hinnant 1363e519524SHoward Hinnant runtime_error::runtime_error(const char* msg) 1373e519524SHoward Hinnant { 1383e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1393e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1403e519524SHoward Hinnant } 1413e519524SHoward Hinnant 1423e519524SHoward Hinnant runtime_error::runtime_error(const runtime_error& le) throw() 1433e519524SHoward Hinnant { 1443e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1453e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1463e519524SHoward Hinnant } 1473e519524SHoward Hinnant 1483e519524SHoward Hinnant runtime_error& 1493e519524SHoward Hinnant runtime_error::operator=(const runtime_error& le) throw() 1503e519524SHoward Hinnant { 1513e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1523e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1533e519524SHoward Hinnant s1 = s2; 1543e519524SHoward Hinnant return *this; 1553e519524SHoward Hinnant } 1563e519524SHoward Hinnant 1573e519524SHoward Hinnant runtime_error::~runtime_error() throw() 1583e519524SHoward Hinnant { 1593e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1603e519524SHoward Hinnant s.~__libcpp_nmstr(); 1613e519524SHoward Hinnant } 1623e519524SHoward Hinnant 1633e519524SHoward Hinnant const char* 1643e519524SHoward Hinnant runtime_error::what() const throw() 1653e519524SHoward Hinnant { 1663e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1673e519524SHoward Hinnant return s.c_str(); 1683e519524SHoward Hinnant } 1693e519524SHoward Hinnant 1703e519524SHoward Hinnant domain_error::~domain_error() throw() {} 1713e519524SHoward Hinnant invalid_argument::~invalid_argument() throw() {} 1723e519524SHoward Hinnant length_error::~length_error() throw() {} 1733e519524SHoward Hinnant out_of_range::~out_of_range() throw() {} 1743e519524SHoward Hinnant 1753e519524SHoward Hinnant range_error::~range_error() throw() {} 1763e519524SHoward Hinnant overflow_error::~overflow_error() throw() {} 1773e519524SHoward Hinnant underflow_error::~underflow_error() throw() {} 1783e519524SHoward Hinnant 1793e519524SHoward Hinnant } // std 180