stdexcept.cpp revision 227825
1227825Stheraven//===------------------------ stdexcept.cpp -------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10227825Stheraven#include "stdexcept" 11227825Stheraven#include "new" 12227825Stheraven#include "string" 13227825Stheraven#include <cstdlib> 14227825Stheraven#include <cstring> 15227825Stheraven#include <cstdint> 16227825Stheraven#include <cstddef> 17227825Stheraven#include "system_error" 18234976Stheraven 19241903Sdim// Note: optimize for size 20241903Sdim 21241903Sdim#pragma GCC visibility push(hidden) 22241903Sdim 23241903Sdimnamespace 24232950Stheraven{ 25241903Sdim 26241903Sdimclass __libcpp_nmstr 27234976Stheraven{ 28227825Stheravenprivate: 29227825Stheraven const char* str_; 30227825Stheraven 31227825Stheraven typedef std::size_t unused_t; 32227825Stheraven typedef std::int32_t count_t; 33227825Stheraven 34227825Stheraven static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 35227825Stheraven sizeof(count_t)); 36227825Stheraven 37227825Stheraven count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 38227825Stheravenpublic: 39227825Stheraven explicit __libcpp_nmstr(const char* msg); 40227825Stheraven __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 41227825Stheraven __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 42241903Sdim ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 43227825Stheraven const char* c_str() const _NOEXCEPT {return str_;} 44227825Stheraven}; 45227825Stheraven 46227825Stheraven__libcpp_nmstr::__libcpp_nmstr(const char* msg) 47227825Stheraven{ 48227825Stheraven std::size_t len = strlen(msg); 49227825Stheraven str_ = new char[len + 1 + offset]; 50227825Stheraven unused_t* c = (unused_t*)str_; 51227825Stheraven c[0] = c[1] = len; 52227825Stheraven str_ += offset; 53227825Stheraven count() = 0; 54227825Stheraven std::strcpy(const_cast<char*>(c_str()), msg); 55227825Stheraven} 56227825Stheraven 57227825Stheraveninline 58227825Stheraven__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 59227825Stheraven : str_(s.str_) 60227825Stheraven{ 61227825Stheraven __sync_add_and_fetch(&count(), 1); 62227825Stheraven} 63227825Stheraven 64227825Stheraven__libcpp_nmstr& 65227825Stheraven__libcpp_nmstr::operator=(const __libcpp_nmstr& s) 66227825Stheraven{ 67227825Stheraven const char* p = str_; 68227825Stheraven str_ = s.str_; 69227825Stheraven __sync_add_and_fetch(&count(), 1); 70227825Stheraven if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 71227825Stheraven delete [] (p-offset); 72227825Stheraven return *this; 73227825Stheraven} 74227825Stheraven 75227825Stheraveninline 76227825Stheraven__libcpp_nmstr::~__libcpp_nmstr() 77227825Stheraven{ 78227825Stheraven if (__sync_add_and_fetch(&count(), -1) < 0) 79227825Stheraven delete [] (str_ - offset); 80241903Sdim} 81227825Stheraven 82227825Stheraven} 83227825Stheraven 84227825Stheraven#pragma GCC visibility pop 85227825Stheraven 86227825Stheravennamespace std // purposefully not using versioning namespace 87227825Stheraven{ 88241903Sdim 89227825Stheravenlogic_error::logic_error(const string& msg) 90227825Stheraven{ 91227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 92227825Stheraven ::new(&s) __libcpp_nmstr(msg.c_str()); 93227825Stheraven} 94227825Stheraven 95227825Stheravenlogic_error::logic_error(const char* msg) 96227825Stheraven{ 97227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 98227825Stheraven ::new(&s) __libcpp_nmstr(msg); 99227825Stheraven} 100227825Stheraven 101227825Stheravenlogic_error::logic_error(const logic_error& le) _NOEXCEPT 102227825Stheraven{ 103227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 104227825Stheraven ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 105227825Stheraven} 106227825Stheraven 107227825Stheravenlogic_error& 108227825Stheravenlogic_error::operator=(const logic_error& le) _NOEXCEPT 109227825Stheraven{ 110227825Stheraven __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 111227825Stheraven const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 112227825Stheraven s1 = s2; 113227825Stheraven return *this; 114227825Stheraven} 115227825Stheraven 116227825Stheravenlogic_error::~logic_error() _NOEXCEPT 117227825Stheraven{ 118227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 119227825Stheraven s.~__libcpp_nmstr(); 120227825Stheraven} 121227825Stheraven 122227825Stheravenconst char* 123227825Stheravenlogic_error::what() const _NOEXCEPT 124227825Stheraven{ 125227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 126232950Stheraven return s.c_str(); 127232950Stheraven} 128227825Stheraven 129227825Stheravenruntime_error::runtime_error(const string& msg) 130227825Stheraven{ 131227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 132227825Stheraven ::new(&s) __libcpp_nmstr(msg.c_str()); 133227825Stheraven} 134227825Stheraven 135227825Stheravenruntime_error::runtime_error(const char* msg) 136227825Stheraven{ 137227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 138227825Stheraven ::new(&s) __libcpp_nmstr(msg); 139227825Stheraven} 140227825Stheraven 141232950Stheravenruntime_error::runtime_error(const runtime_error& le) _NOEXCEPT 142232950Stheraven{ 143227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 144227825Stheraven ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 145227825Stheraven} 146227825Stheraven 147227825Stheravenruntime_error& 148227825Stheravenruntime_error::operator=(const runtime_error& le) _NOEXCEPT 149227825Stheraven{ 150227825Stheraven __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 151227825Stheraven const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 152227825Stheraven s1 = s2; 153227825Stheraven return *this; 154227825Stheraven} 155227825Stheraven 156227825Stheravenruntime_error::~runtime_error() _NOEXCEPT 157227825Stheraven{ 158227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 159227825Stheraven s.~__libcpp_nmstr(); 160227825Stheraven} 161227825Stheraven 162227825Stheravenconst char* 163227825Stheravenruntime_error::what() const _NOEXCEPT 164227825Stheraven{ 165227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 166227825Stheraven return s.c_str(); 167227825Stheraven} 168227825Stheraven 169227825Stheravendomain_error::~domain_error() _NOEXCEPT {} 170232950Stheraveninvalid_argument::~invalid_argument() _NOEXCEPT {} 171232950Stheravenlength_error::~length_error() _NOEXCEPT {} 172227825Stheravenout_of_range::~out_of_range() _NOEXCEPT {} 173227825Stheraven 174227825Stheravenrange_error::~range_error() _NOEXCEPT {} 175227825Stheravenoverflow_error::~overflow_error() _NOEXCEPT {} 176227825Stheravenunderflow_error::~underflow_error() _NOEXCEPT {} 177227825Stheraven 178227825Stheraven} // std 179227825Stheraven