]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/flex/vectorstringstorage.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / flex / vectorstringstorage.h
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
91         VectorStringStorage(const VectorStringStorage &s) : base(s)
92         { }
93
94         VectorStringStorage(const A &a) : base(1, value_type(), a)
95         { }
96
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
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
120         iterator begin()
121         {
122                 return base::begin();
123         }
124
125         const_iterator begin() const
126         {
127                 return base::begin();
128         }
129
130         iterator end()
131         {
132                 return base::end() - 1;
133         }
134
135         const_iterator end() const
136         {
137                 return base::end() - 1;
138         }
139
140         size_type size() const
141         {
142                 return base::size() - 1;
143         }
144
145         size_type max_size() const
146         {
147                 return base::max_size() - 1;
148         }
149
150         size_type capacity() const
151         {
152                 return base::capacity() - 1;
153         }
154
155         void reserve(size_type res_arg)
156         {
157                 assert(res_arg < max_size());
158                 base::reserve(res_arg + 1);
159         }
160
161         template <class ForwardIterator>
162         void append(ForwardIterator b, ForwardIterator e)
163         {
164                 const typename std::iterator_traits<ForwardIterator>::difference_type
165                 sz = std::distance(b, e);
166                 assert(sz >= 0);
167                 if (sz == 0) return;
168                 base::reserve(base::size() + sz);
169                 const value_type &v = *b;
170                 struct OnBlockExit
171                 {
172                         VectorStringStorage *that;
173                         ~OnBlockExit()
174                         {
175                                 that->base::push_back(value_type());
176                         }
177                 } onBlockExit = { this };
178                 (void) onBlockExit;
179                 assert(!base::empty());
180                 assert(base::back() == value_type());
181                 base::back() = v;
182                 base::insert(base::end(), ++b, e);
183         }
184
185         void resize(size_type n, E c)
186         {
187                 base::reserve(n + 1);
188                 base::back() = c;
189                 base::resize(n + 1, c);
190                 base::back() = E();
191         }
192
193         void swap(VectorStringStorage &rhs)
194         {
195                 base::swap(rhs);
196         }
197
198         const E *c_str() const
199         {
200                 return &*begin();
201         }
202
203         const E *data() const
204         {
205                 return &*begin();
206         }
207
208         A get_allocator() const
209         {
210                 return base::get_allocator();
211         }
212 };
213
214
215 #endif // VECTOR_STRING_STORAGE_INC_