string.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,794 行 · 第 1/5 页

HPP
1,794
字号
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost// Software License, Version 1.0. (See accompanying file// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.//////////////////////////////////////////////////////////////////////////////////// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008// Renaming, isolating and porting to generic algorithms. Pointer typedef // set to allocator::pointer to allow placing it in shared memory./////////////////////////////////////////////////////////////////////////////////// Copyright (c) 1994// Hewlett-Packard Company// // Permission to use, copy, modify, distribute and sell this software// and its documentation for any purpose is hereby granted without fee,// provided that the above copyright notice appear in all copies and// that both that copyright notice and this permission notice appear// in supporting documentation.  Hewlett-Packard Company makes no// representations about the suitability of this software for any// purpose.  It is provided "as is" without express or implied warranty.#ifndef BOOST_INTERPROCESS_STRING_HPP#define BOOST_INTERPROCESS_STRING_HPP#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/interprocess/interprocess_fwd.hpp>#include <boost/interprocess/detail/utilities.hpp>#include <boost/interprocess/detail/algorithms.hpp>#include <boost/interprocess/detail/min_max.hpp>#include <boost/interprocess/detail/iterators.hpp>#include <boost/interprocess/detail/version_type.hpp>#include <boost/interprocess/allocators/allocation_type.hpp>#include <boost/interprocess/detail/mpl.hpp>#include <boost/interprocess/detail/move.hpp>#include <boost/static_assert.hpp>#include <functional>#include <string>#include <stdexcept>      #include <utility>  #include <iterator>#include <memory>#include <algorithm>#include <iosfwd>#include <istream>#include <ostream>#include <ios>#include <locale>#include <cstddef>#include <climits>#include <boost/interprocess/detail/type_traits.hpp>#include <boost/detail/no_exceptions_support.hpp>#include <boost/type_traits/has_trivial_destructor.hpp>namespace boost {namespace interprocess {namespace detail {/// @cond// ------------------------------------------------------------// Class basic_string_base.  // basic_string_base is a helper class that makes it it easier to write// an exception-safe version of basic_string.  The constructor allocates,// but does not initialize, a block of memory.  The destructor// deallocates, but does not destroy elements within, a block of// memory.  The destructor assumes that the memory either is the internal buffer, // or else points to a block of memory that was allocated using _String_base's // allocator and whose size is this->m_storage.template <class A>class basic_string_base{   basic_string_base(); public:   typedef A allocator_type;   //! The stored allocator type   typedef allocator_type                          stored_allocator_type;   typedef typename A::pointer     pointer;   typedef typename A::value_type  value_type;   typedef typename A::size_type   size_type;   basic_string_base(const allocator_type& a)      : members_(a)   {  init(); }   basic_string_base(const allocator_type& a, std::size_t n)      : members_(a)   {        this->init();       this->allocate_initial_block(n);   }   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE   basic_string_base(const detail::moved_object<basic_string_base<A> >& b)      :  members_(b.get().members_)   {        init();      this->swap(b.get());    }   #else   basic_string_base(basic_string_base<A> && b)      :  members_(b.members_)   {        init();      this->swap(b);    }   #endif   ~basic_string_base()    {        this->deallocate_block();       if(!this->is_short()){         static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();      }   }   private:   //This is the structure controlling a long string    struct long_t   {      size_type      is_short  : 1;      size_type      length    : (sizeof(size_type)*CHAR_BIT - 1);      size_type      storage;      pointer        start;      long_t()      {}      long_t(const long_t &other)      {         this->is_short = other.is_short;         length   = other.length;         storage  = other.storage;         start    = other.start;      }      long_t &operator =(const long_t &other)      {         this->is_short = other.is_short;         length   = other.length;         storage  = other.storage;         start    = other.start;         return *this;      }   };   //This basic type should have the same alignment as long_t//iG   typedef typename type_with_alignment<detail::alignment_of<long_t>::value>::type//      long_alignment_type;   typedef void *long_alignment_type;   BOOST_STATIC_ASSERT((detail::alignment_of<long_alignment_type>::value %                         detail::alignment_of<long_t>::value) == 0);   //This type is the first part of the structure controlling a short string   //The "data" member stores   struct short_header   {      unsigned char  is_short  : 1;      unsigned char  length    : (CHAR_BIT - 1);   };   //This type has the same alignment and size as long_t but it's POD   //so, unlike long_t, it can be placed in a union   struct long_raw_t   {      long_alignment_type  a;      unsigned char        b[sizeof(long_t) - sizeof(long_alignment_type)];   };   protected:   static const size_type  MinInternalBufferChars = 8;   static const size_type  AlignmentOfValueType =      alignment_of<value_type>::value;   static const size_type  ShortDataOffset =      detail::ct_rounded_size<sizeof(short_header),  AlignmentOfValueType>::value;   static const size_type  ZeroCostInternalBufferChars =      (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);   static const size_type  UnalignedFinalInternalBufferChars =       (ZeroCostInternalBufferChars > MinInternalBufferChars) ?                ZeroCostInternalBufferChars : MinInternalBufferChars;   struct short_t   {      short_header   h;       value_type     data[UnalignedFinalInternalBufferChars];   };   union repr_t   {      long_raw_t  r;      short_t     s;      short_t &short_repr() const      {  return *const_cast<short_t *>(&s);  }      long_t &long_repr() const      {  return *static_cast<long_t*>(const_cast<void*>(static_cast<const void*>(&r)));  }   };   struct members_holder      :  public A   {      members_holder(const A &a)         :  A(a)      {}      repr_t m_repr;   } members_;   const A &alloc() const   {  return members_;  }   A &alloc()   {  return members_;  }   static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);   private:   static const size_type MinAllocation = InternalBufferChars*2;   protected:   bool is_short() const   {  return static_cast<bool>(this->members_.m_repr.s.h.is_short != 0);  }   void is_short(bool yes)   {        if(yes && !this->is_short()){         static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();      }      else{         new(static_cast<void*>(&this->members_.m_repr.r))long_t();      }      this->members_.m_repr.s.h.is_short = yes;   }   private:   void init()   {      this->members_.m_repr.s.h.is_short = 1;      this->members_.m_repr.s.h.length   = 0;   }   protected:   typedef detail::integral_constant<unsigned, 1>      allocator_v1;   typedef detail::integral_constant<unsigned, 2>      allocator_v2;   typedef detail::integral_constant<unsigned,      boost::interprocess::detail::version<A>::value> alloc_version;   std::pair<pointer, bool>      allocation_command(allocation_type command,                         size_type limit_size,                          size_type preferred_size,                         size_type &received_size, pointer reuse = 0)   {      if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){         reuse = pointer(0);         command &= ~(expand_fwd | expand_bwd);      }      return this->allocation_command         (command, limit_size, preferred_size, received_size, reuse, alloc_version());   }   std::pair<pointer, bool>      allocation_command(allocation_type command,                         size_type limit_size,                          size_type preferred_size,                         size_type &received_size,                         const pointer &reuse,                         allocator_v1)   {      (void)limit_size;      (void)reuse;      if(!(command & allocate_new))         return std::pair<pointer, bool>(pointer(0), 0);      received_size = preferred_size;      return std::make_pair(this->alloc().allocate(received_size), false);   }   std::pair<pointer, bool>      allocation_command(allocation_type command,                         size_type limit_size,                          size_type preferred_size,                         size_type &received_size,                         pointer reuse,                         allocator_v2)   {      return this->alloc().allocation_command(command, limit_size, preferred_size,                                               received_size, reuse);   }   size_type next_capacity(size_type additional_objects) const   {  return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects);  }   void deallocate(pointer p, std::size_t n)    {        if (p && (n > InternalBufferChars))         this->alloc().deallocate(p, n);   }   void construct(pointer p, const value_type &value = value_type())   {  new((void*)detail::get_pointer(p)) value_type(value);   }   void destroy(pointer p, size_type n)   {      for(; n--; ++p)         detail::get_pointer(p)->~value_type();   }   void destroy(pointer p)   {  detail::get_pointer(p)->~value_type(); }   void allocate_initial_block(std::size_t n)   {      if (n <= this->max_size()) {         if(n > InternalBufferChars){            size_type new_cap = this->next_capacity(n);            pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;            this->is_short(false);            this->priv_addr(p);            this->priv_size(0);            this->priv_storage(new_cap);         }      }      else         throw_length_error();   }   void deallocate_block()    {  this->deallocate(this->priv_addr(), this->priv_storage());  }         std::size_t max_size() const   {  return this->alloc().max_size() - 1; }   // Helper functions for exception handling.   void throw_length_error() const   {  throw(std::length_error("basic_string"));  }   void throw_out_of_range() const   {  throw(std::out_of_range("basic_string"));  }   protected:   size_type priv_capacity() const   { return this->priv_storage() - 1; }   pointer priv_addr() const   {  return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?