1 //////////////////////////////////////////////////////////////////////////////// 2 // flex_string 3 // Copyright (c) 2001 by Andrei Alexandrescu 4 // Permission to use, copy, modify, distribute and sell this software for any 5 // purpose is hereby granted without fee, provided that the above copyright 6 // notice appear in all copies and that both that copyright notice and this 7 // permission notice appear in supporting documentation. 8 // The author makes no representations about the 9 // suitability of this software for any purpose. It is provided "as is" 10 // without express or implied warranty. 11 //////////////////////////////////////////////////////////////////////////////// 12 13 #ifndef VECTOR_STRING_STORAGE_INC_ 14 #define VECTOR_STRING_STORAGE_INC_ 15 16 // $Id: vectorstringstorage.h 754 2006-10-17 19:59:11Z syntheticpp $ 17 18 19 /* This is the template for a storage policy 20 //////////////////////////////////////////////////////////////////////////////// 21 template <typename E, class A = @> 22 class StoragePolicy 23 { 24 typedef E value_type; 25 typedef @ iterator; 26 typedef @ const_iterator; 27 typedef A allocator_type; 28 typedef @ size_type; 29 30 StoragePolicy(const StoragePolicy& s); 31 StoragePolicy(const A&); 32 StoragePolicy(const E* s, size_type len, const A&); 33 StoragePolicy(size_type len, E c, const A&); 34 ~StoragePolicy(); 35 36 iterator begin(); 37 const_iterator begin() const; 38 iterator end(); 39 const_iterator end() const; 40 41 size_type size() const; 42 size_type max_size() const; 43 size_type capacity() const; 44 45 void reserve(size_type res_arg); 46 47 void append(const E* s, size_type sz); 48 49 template <class InputIterator> 50 void append(InputIterator b, InputIterator e); 51 52 void resize(size_type newSize, E fill); 53 54 void swap(StoragePolicy& rhs); 55 56 const E* c_str() const; 57 const E* data() const; 58 59 A get_allocator() const; 60 }; 61 //////////////////////////////////////////////////////////////////////////////// 62 */ 63 64 #include <memory> 65 #include <vector> 66 #include <algorithm> 67 #include <functional> 68 #include <cassert> 69 #include <limits> 70 #include <stdexcept> 71 72 //////////////////////////////////////////////////////////////////////////////// 73 // class template VectorStringStorage 74 // Uses std::vector 75 // Takes advantage of the Empty Base Optimization if available 76 //////////////////////////////////////////////////////////////////////////////// 77 78 template <typename E, class A = std::allocator<E> > 79 class VectorStringStorage : protected std::vector<E, A> 80 { 81 typedef std::vector<E, A> base; 82 83 public: // protected: 84 typedef E value_type; 85 typedef typename base::iterator iterator; 86 typedef typename base::const_iterator const_iterator; 87 typedef A allocator_type; 88 typedef typename A::size_type size_type; 89 typedef typename A::reference reference; 90 VectorStringStorage(const VectorStringStorage & s)91 VectorStringStorage(const VectorStringStorage& s) : base(s) 92 { } 93 VectorStringStorage(const A & a)94 VectorStringStorage(const A& a) : base(1, value_type(), a) 95 { } 96 VectorStringStorage(const value_type * s,size_type len,const A & a)97 VectorStringStorage(const value_type* s, size_type len, const A& a) 98 : base(a) 99 { 100 base::reserve(len + 1); 101 base::insert(base::end(), s, s + len); 102 // Terminating zero 103 base::push_back(value_type()); 104 } 105 VectorStringStorage(size_type len,E c,const A & a)106 VectorStringStorage(size_type len, E c, const A& a) 107 : base(len + 1, c, a) 108 { 109 // Terminating zero 110 base::back() = value_type(); 111 } 112 113 VectorStringStorage& operator=(const VectorStringStorage& rhs) 114 { 115 base& v = *this; 116 v = rhs; 117 return *this; 118 } 119 begin()120 iterator begin() 121 { return base::begin(); } 122 begin()123 const_iterator begin() const 124 { return base::begin(); } 125 end()126 iterator end() 127 { return base::end() - 1; } 128 end()129 const_iterator end() const 130 { return base::end() - 1; } 131 size()132 size_type size() const 133 { return base::size() - 1; } 134 max_size()135 size_type max_size() const 136 { return base::max_size() - 1; } 137 capacity()138 size_type capacity() const 139 { return base::capacity() - 1; } 140 reserve(size_type res_arg)141 void reserve(size_type res_arg) 142 { 143 assert(res_arg < max_size()); 144 base::reserve(res_arg + 1); 145 } 146 147 template <class ForwardIterator> append(ForwardIterator b,ForwardIterator e)148 void append(ForwardIterator b, ForwardIterator e) 149 { 150 const typename std::iterator_traits<ForwardIterator>::difference_type 151 sz = std::distance(b, e); 152 assert(sz >= 0); 153 if (sz == 0) return; 154 base::reserve(base::size() + sz); 155 const value_type & v = *b; 156 struct OnBlockExit 157 { 158 VectorStringStorage * that; 159 ~OnBlockExit() 160 { 161 that->base::push_back(value_type()); 162 } 163 } onBlockExit = { this }; 164 (void) onBlockExit; 165 assert(!base::empty()); 166 assert(base::back() == value_type()); 167 base::back() = v; 168 base::insert(base::end(), ++b, e); 169 } 170 resize(size_type n,E c)171 void resize(size_type n, E c) 172 { 173 base::reserve(n + 1); 174 base::back() = c; 175 base::resize(n + 1, c); 176 base::back() = E(); 177 } 178 swap(VectorStringStorage & rhs)179 void swap(VectorStringStorage& rhs) 180 { base::swap(rhs); } 181 c_str()182 const E* c_str() const 183 { return &*begin(); } 184 data()185 const E* data() const 186 { return &*begin(); } 187 get_allocator()188 A get_allocator() const 189 { return base::get_allocator(); } 190 }; 191 192 193 #endif // VECTOR_STRING_STORAGE_INC_ 194