Path: blob/master/libs/c++abi/src/include/refstring.h
12346 views
//===------------------------ __refstring ---------------------------------===//1//2// The LLVM Compiler Infrastructure3//4// This file is dual licensed under the MIT and the University of Illinois Open5// Source Licenses. See LICENSE.TXT for details.6//7//===----------------------------------------------------------------------===//89// FIXME: This file is copied from libcxx/src/include/refstring.h. Instead of10// duplicating the file in libc++abi we should require that the libc++ sources11// are available when building libc++abi.1213#ifndef _LIBCPPABI_REFSTRING_H14#define _LIBCPPABI_REFSTRING_H1516#include <__config>17#include <stdexcept>18#include <cstddef>19#include <cstring>20#ifdef __APPLE__21#include <dlfcn.h>22#include <mach-o/dyld.h>23#endif24#include "atomic_support.h"2526_LIBCPP_BEGIN_NAMESPACE_STD2728namespace __refstring_imp { namespace {29typedef int count_t;3031struct _Rep_base {32std::size_t len;33std::size_t cap;34count_t count;35};3637inline _Rep_base* rep_from_data(const char *data_) noexcept {38char *data = const_cast<char *>(data_);39return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));40}4142inline char * data_from_rep(_Rep_base *rep) noexcept {43char *data = reinterpret_cast<char *>(rep);44return data + sizeof(*rep);45}4647#if defined(__APPLE__)48inline49const char* compute_gcc_empty_string_storage() _NOEXCEPT50{51void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);52if (handle == nullptr)53return nullptr;54void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");55if (sym == nullptr)56return nullptr;57return data_from_rep(reinterpret_cast<_Rep_base *>(sym));58}5960inline61const char*62get_gcc_empty_string_storage() _NOEXCEPT63{64static const char* p = compute_gcc_empty_string_storage();65return p;66}67#endif6869}} // namespace __refstring_imp7071using namespace __refstring_imp;7273inline74__libcpp_refstring::__libcpp_refstring(const char* msg) {75std::size_t len = strlen(msg);76_Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));77rep->len = len;78rep->cap = len;79rep->count = 0;80char *data = data_from_rep(rep);81std::memcpy(data, msg, len + 1);82__imp_ = data;83}8485inline86__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT87: __imp_(s.__imp_)88{89if (__uses_refcount())90__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);91}9293inline94__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {95bool adjust_old_count = __uses_refcount();96struct _Rep_base *old_rep = rep_from_data(__imp_);97__imp_ = s.__imp_;98if (__uses_refcount())99__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);100if (adjust_old_count)101{102if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)103{104::operator delete(old_rep);105}106}107return *this;108}109110inline111__libcpp_refstring::~__libcpp_refstring() {112if (__uses_refcount()) {113_Rep_base* rep = rep_from_data(__imp_);114if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {115::operator delete(rep);116}117}118}119120inline121bool __libcpp_refstring::__uses_refcount() const {122#ifdef __APPLE__123return __imp_ != get_gcc_empty_string_storage();124#else125return true;126#endif127}128129_LIBCPP_END_NAMESPACE_STD130131#endif //_LIBCPPABI_REFSTRING_H132133134