Alien-boost-mini

 view release on metacpan or  search on metacpan

include/boost/container/string.hpp  view on Meta::CPAN


   const Allocator &alloc() const
   {  return members_;  }

   Allocator &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
   {
      //Access and copy (to avoid UB) the first byte of the union to know if the
      //active representation is short or long
      short_header hdr;
      BOOST_STATIC_ASSERT((sizeof(short_header) == 1));
      *(unsigned char*)&hdr = *(unsigned char*)&this->members_.m_repr;
      return hdr.is_short != 0;
   }

   void is_short(bool yes)
   {
      const bool was_short = this->is_short();
      if(yes && !was_short){
         allocator_traits_type::destroy
            ( this->alloc()
            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
            );
         this->members_.m_repr.s.h.is_short = true;
      }
      else if(!yes && was_short){
         allocator_traits_type::construct
            ( this->alloc()
            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
            );
         this->members_.m_repr.s.h.is_short = false;
      }
   }

   private:
   void init()
   {
      this->members_.m_repr.s.h.is_short = 1;
      this->members_.m_repr.s.h.length   = 0;
   }

   protected:

   typedef dtl::integral_constant<unsigned,
      boost::container::dtl::version<Allocator>::value> alloc_version;

   pointer allocation_command(allocation_type command,
                         size_type limit_size,
                         size_type &prefer_in_recvd_out_size,
                         pointer &reuse)
   {
      if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
         reuse = 0;
         command &= ~(expand_fwd | expand_bwd);
      }
      return dtl::allocator_version_traits<Allocator>::allocation_command
         (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
   }

   size_type next_capacity(size_type additional_objects) const
   {
      return growth_factor_100()
            ( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc()));
   }

   void deallocate(pointer p, size_type n)
   {
      if (p && (n > InternalBufferChars))
         this->alloc().deallocate(p, n);
   }

   void construct(pointer p, const value_type &value = value_type())
   {
      allocator_traits_type::construct
         ( this->alloc()
         , boost::movelib::to_raw_pointer(p)
         , value
         );
   }

   void destroy(pointer p, size_type n)
   {
      value_type *raw_p = boost::movelib::to_raw_pointer(p);
      for(; n--; ++raw_p){
         allocator_traits_type::destroy( this->alloc(), raw_p);
      }
   }

   void destroy(pointer p)
   {
      allocator_traits_type::destroy
         ( this->alloc()
         , boost::movelib::to_raw_pointer(p)
         );
   }

   void allocate_initial_block(size_type n)
   {
      if (n <= this->max_size()) {
         if(n > InternalBufferChars){
            size_type new_cap = this->next_capacity(n);
            pointer reuse = 0;
            pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
            this->is_short(false);
            this->priv_long_addr(p);
            this->priv_long_size(0);
            this->priv_storage(new_cap);
         }
      }
      else{
         throw_length_error("basic_string::allocate_initial_block max_size() exceeded");
      }
   }

include/boost/container/string.hpp  view on Meta::CPAN

      return this->priv_addr() + new_offset;
   }

   //! <b>Requires</b>: p is a valid iterator on *this.
   //!
   //! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
   //!
   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
   iterator insert(const_iterator p, size_type n, CharT c)
   {  return this->insert(p, cvalue_iterator(c, n), cvalue_iterator());  }

   //! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
   //!
   //! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
   //!
   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
   template <class InputIter>
   iterator insert(const_iterator p, InputIter first, InputIter last
      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      , typename dtl::disable_if_or
         < void
         , dtl::is_convertible<InputIter, size_type>
         , dtl::is_not_input_iterator<InputIter>
         >::type * = 0
      #endif
      )
   {
      const size_type n_pos = p - this->cbegin();
      for ( ; first != last; ++first, ++p) {
         p = this->insert(p, *first);
      }
      return this->begin() + n_pos;
   }

   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
   template <class ForwardIter>
   iterator insert(const_iterator p, ForwardIter first, ForwardIter last
      , typename dtl::disable_if_or
         < void
         , dtl::is_convertible<ForwardIter, size_type>
         , dtl::is_input_iterator<ForwardIter>
         >::type * = 0
      )
   {
      const size_type n_pos = p - this->cbegin();
      if (first != last) {
         const size_type n = boost::container::iterator_distance(first, last);
         const size_type old_size = this->priv_size();
         const size_type remaining = this->capacity() - old_size;
         const pointer old_start = this->priv_addr();
         bool enough_capacity = false;
         size_type new_cap = 0;

         //Check if we have enough capacity
         pointer hint = pointer();
         pointer allocation_ret = pointer();
         if (remaining >= n){
            enough_capacity = true;
         }
         else {
            //Otherwise expand current buffer or allocate new storage
            new_cap  = this->next_capacity(n);
            hint = old_start;
            allocation_ret = this->allocation_command
                  (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);

            //Check forward expansion
            if(old_start == allocation_ret){
               enough_capacity = true;
               this->priv_storage(new_cap);
            }
         }

         //Reuse same buffer
         if(enough_capacity){
            const size_type elems_after = old_size - (p - old_start);
            const size_type old_length = old_size;
            if (elems_after >= n) {
               const pointer pointer_past_last = old_start + old_size + 1;
               priv_uninitialized_copy(old_start + (old_size - n + 1),
                                       pointer_past_last, pointer_past_last);

               this->priv_size(old_size+n);
               Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
                           boost::movelib::to_raw_pointer(p),
                           (elems_after - n) + 1);
               this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
            }
            else {
               ForwardIter mid = first;
               boost::container::iterator_advance(mid, elems_after + 1);

               priv_uninitialized_copy(mid, last, old_start + old_size + 1);
               const size_type newer_size = old_size + (n - elems_after);
               this->priv_size(newer_size);
               priv_uninitialized_copy
                  (p, const_iterator(old_start + old_length + 1),
                  old_start + newer_size);
               this->priv_size(newer_size + elems_after);
               this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
            }
         }
         else{
            pointer new_start = allocation_ret;
            if(!hint){
               //Copy data to new buffer
               size_type new_length = 0;
               //This can't throw, since characters are POD
               new_length += priv_uninitialized_copy
                              (const_iterator(old_start), p, new_start);
               new_length += priv_uninitialized_copy
                              (first, last, new_start + new_length);
               new_length += priv_uninitialized_copy
                              (p, const_iterator(old_start + old_size),
                              new_start + new_length);
               this->priv_construct_null(new_start + new_length);

               this->deallocate_block();
               this->is_short(false);
               this->priv_long_addr(new_start);
               this->priv_long_size(new_length);
               this->priv_long_storage(new_cap);
            }
            else{
               //value_type is POD, so backwards expansion is much easier



( run in 1.324 second using v1.01-cache-2.11-cpan-5b529ec07f3 )