stdexcept.cpp revision 227825
1//===------------------------ stdexcept.cpp -------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "stdexcept" 11#include "new" 12#include "string" 13#include <cstdlib> 14#include <cstring> 15#include <cstdint> 16#include <cstddef> 17#include "system_error" 18 19// Note: optimize for size 20 21#pragma GCC visibility push(hidden) 22 23namespace 24{ 25 26class __libcpp_nmstr 27{ 28private: 29 const char* str_; 30 31 typedef std::size_t unused_t; 32 typedef std::int32_t count_t; 33 34 static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 35 sizeof(count_t)); 36 37 count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 38public: 39 explicit __libcpp_nmstr(const char* msg); 40 __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 41 __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 42 ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 43 const char* c_str() const _NOEXCEPT {return str_;} 44}; 45 46__libcpp_nmstr::__libcpp_nmstr(const char* msg) 47{ 48 std::size_t len = strlen(msg); 49 str_ = new char[len + 1 + offset]; 50 unused_t* c = (unused_t*)str_; 51 c[0] = c[1] = len; 52 str_ += offset; 53 count() = 0; 54 std::strcpy(const_cast<char*>(c_str()), msg); 55} 56 57inline 58__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 59 : str_(s.str_) 60{ 61 __sync_add_and_fetch(&count(), 1); 62} 63 64__libcpp_nmstr& 65__libcpp_nmstr::operator=(const __libcpp_nmstr& s) 66{ 67 const char* p = str_; 68 str_ = s.str_; 69 __sync_add_and_fetch(&count(), 1); 70 if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 71 delete [] (p-offset); 72 return *this; 73} 74 75inline 76__libcpp_nmstr::~__libcpp_nmstr() 77{ 78 if (__sync_add_and_fetch(&count(), -1) < 0) 79 delete [] (str_ - offset); 80} 81 82} 83 84#pragma GCC visibility pop 85 86namespace std // purposefully not using versioning namespace 87{ 88 89logic_error::logic_error(const string& msg) 90{ 91 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 92 ::new(&s) __libcpp_nmstr(msg.c_str()); 93} 94 95logic_error::logic_error(const char* msg) 96{ 97 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 98 ::new(&s) __libcpp_nmstr(msg); 99} 100 101logic_error::logic_error(const logic_error& le) _NOEXCEPT 102{ 103 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 104 ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 105} 106 107logic_error& 108logic_error::operator=(const logic_error& le) _NOEXCEPT 109{ 110 __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 111 const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 112 s1 = s2; 113 return *this; 114} 115 116logic_error::~logic_error() _NOEXCEPT 117{ 118 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 119 s.~__libcpp_nmstr(); 120} 121 122const char* 123logic_error::what() const _NOEXCEPT 124{ 125 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 126 return s.c_str(); 127} 128 129runtime_error::runtime_error(const string& msg) 130{ 131 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 132 ::new(&s) __libcpp_nmstr(msg.c_str()); 133} 134 135runtime_error::runtime_error(const char* msg) 136{ 137 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 138 ::new(&s) __libcpp_nmstr(msg); 139} 140 141runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT 142{ 143 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 144 ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 145} 146 147runtime_error& 148runtime_error::operator=(const runtime_error& le) _NOEXCEPT 149{ 150 __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 151 const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 152 s1 = s2; 153 return *this; 154} 155 156runtime_error::~runtime_error() _NOEXCEPT 157{ 158 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 159 s.~__libcpp_nmstr(); 160} 161 162const char* 163runtime_error::what() const _NOEXCEPT 164{ 165 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 166 return s.c_str(); 167} 168 169domain_error::~domain_error() _NOEXCEPT {} 170invalid_argument::~invalid_argument() _NOEXCEPT {} 171length_error::~length_error() _NOEXCEPT {} 172out_of_range::~out_of_range() _NOEXCEPT {} 173 174range_error::~range_error() _NOEXCEPT {} 175overflow_error::~overflow_error() _NOEXCEPT {} 176underflow_error::~underflow_error() _NOEXCEPT {} 177 178} // std 179