1
////////////////////////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////////////////////////
13
#ifndef COW_STRING_OPT_INC_
14
#define COW_STRING_OPT_INC_
16
// $Id: cowstringopt.h 754 2006-10-17 19:59:11Z syntheticpp $
19
////////////////////////////////////////////////////////////////////////////////
20
// class template CowStringOpt
21
// Implements Copy on Write over any storage
22
////////////////////////////////////////////////////////////////////////////////
25
/* This is the template for a storage policy
26
////////////////////////////////////////////////////////////////////////////////
27
template <typename E, class A = @>
32
typedef @ const_iterator;
33
typedef A allocator_type;
36
StoragePolicy(const StoragePolicy& s);
37
StoragePolicy(const A&);
38
StoragePolicy(const E* s, size_type len, const A&);
39
StoragePolicy(size_type len, E c, const A&);
43
const_iterator begin() const;
45
const_iterator end() const;
47
size_type size() const;
48
size_type max_size() const;
49
size_type capacity() const;
51
void reserve(size_type res_arg);
53
void append(const E* s, size_type sz);
55
template <class InputIterator>
56
void append(InputIterator b, InputIterator e);
58
void resize(size_type newSize, E fill);
60
void swap(StoragePolicy& rhs);
62
const E* c_str() const;
63
const E* data() const;
65
A get_allocator() const;
67
////////////////////////////////////////////////////////////////////////////////
76
#include "flex_string_details.h"
79
////////////////////////////////////////////////////////////////////////////////
80
// class template CowStringOpt
81
// Implements Copy on Write over any storage
82
////////////////////////////////////////////////////////////////////////////////
84
template <class Storage, typename Align = typename Storage::value_type*>
87
typedef typename Storage::value_type E;
88
typedef typename flex_string_details::get_unsigned<E>::result RefCountType;
92
typedef typename Storage::iterator iterator;
93
typedef typename Storage::const_iterator const_iterator;
94
typedef typename Storage::allocator_type allocator_type;
95
typedef typename allocator_type::size_type size_type;
96
typedef typename Storage::reference reference;
101
mutable char buf_[sizeof(Storage)];
105
Storage& Data() const
106
{ return *reinterpret_cast<Storage*>(buf_); }
108
RefCountType GetRefs() const
110
const Storage& d = Data();
111
assert(d.size() > 0);
112
assert(*d.begin() > 0);
119
assert(d.size() > 0);
120
return reinterpret_cast<RefCountType&>(*d.begin());
123
void MakeUnique() const
125
assert(GetRefs() >= 1);
126
if (GetRefs() == 1) return;
130
char buf_[sizeof(Storage)];
135
*new(temp.buf_) Storage(Data()),
136
flex_string_details::Shallow());
141
CowStringOpt(const CowStringOpt& s)
143
if (s.GetRefs() == std::numeric_limits<RefCountType>::max())
145
// must make a brand new copy
146
new(buf_) Storage(s.Data()); // non shallow
151
new(buf_) Storage(s.Data(), flex_string_details::Shallow());
154
assert(Data().size() > 0);
157
CowStringOpt(const allocator_type& a)
159
new(buf_) Storage(1, 1, a);
162
CowStringOpt(const E* s, size_type len, const allocator_type& a)
164
// Warning - MSVC's debugger has trouble tracing through the code below.
165
// It seems to be a const-correctness issue
167
new(buf_) Storage(a);
168
Data().reserve(len + 1);
170
Data().append(s, s + len);
173
CowStringOpt(size_type len, E c, const allocator_type& a)
175
new(buf_) Storage(len + 1, c, a);
179
CowStringOpt& operator=(const CowStringOpt& rhs)
181
CowStringOpt(rhs).swap(*this);
187
assert(Data().size() > 0);
188
if (--Refs() == 0) Data().~Storage();
193
assert(Data().size() > 0);
195
return Data().begin() + 1;
198
const_iterator begin() const
200
assert(Data().size() > 0);
201
return Data().begin() + 1;
210
const_iterator end() const
215
size_type size() const
217
assert(Data().size() > 0);
218
return Data().size() - 1;
221
size_type max_size() const
223
assert(Data().max_size() > 0);
224
return Data().max_size() - 1;
227
size_type capacity() const
229
assert(Data().capacity() > 0);
230
return Data().capacity() - 1;
233
void resize(size_type n, E c)
235
assert(Data().size() > 0);
237
Data().resize(n + 1, c);
240
template <class FwdIterator>
241
void append(FwdIterator b, FwdIterator e)
247
void reserve(size_type res_arg)
249
if (capacity() > res_arg) return;
251
Data().reserve(res_arg + 1);
254
void swap(CowStringOpt& rhs)
256
Data().swap(rhs.Data());
259
const E* c_str() const
261
assert(Data().size() > 0);
262
return Data().c_str() + 1;
265
const E* data() const
267
assert(Data().size() > 0);
268
return Data().data() + 1;
271
allocator_type get_allocator() const
273
return Data().get_allocator();
278
#endif // COW_STRING_OPT_INC_