~ubuntu-branches/ubuntu/wily/tora/wily-proposed

« back to all changes in this revision

Viewing changes to ext/loki/loki-0.1.6/include/loki/flex/cowstringopt.h

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2007-10-21 21:17:23 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20071021211723-pq817gwdkt8hwetj
Tags: 1.3.22-1ubuntu1
* Merge from Debian unstable (LP: #149343). Remaining Ubuntu changes:
  - debian/rules: call dh_icons
  - Remove g++ build dependency
  - Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 COW_STRING_OPT_INC_
 
14
#define COW_STRING_OPT_INC_
 
15
 
 
16
// $Id: cowstringopt.h 754 2006-10-17 19:59:11Z syntheticpp $
 
17
 
 
18
 
 
19
////////////////////////////////////////////////////////////////////////////////
 
20
// class template CowStringOpt
 
21
// Implements Copy on Write over any storage
 
22
////////////////////////////////////////////////////////////////////////////////
 
23
 
 
24
 
 
25
/* This is the template for a storage policy
 
26
////////////////////////////////////////////////////////////////////////////////
 
27
template <typename E, class A = @>
 
28
class StoragePolicy
 
29
{
 
30
    typedef E value_type;
 
31
    typedef @ iterator;
 
32
    typedef @ const_iterator;
 
33
    typedef A allocator_type;
 
34
    typedef @ size_type;
 
35
    
 
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&);
 
40
    ~StoragePolicy();
 
41
 
 
42
    iterator begin();
 
43
    const_iterator begin() const;
 
44
    iterator end();
 
45
    const_iterator end() const;
 
46
    
 
47
    size_type size() const;
 
48
    size_type max_size() const;
 
49
    size_type capacity() const;
 
50
 
 
51
    void reserve(size_type res_arg);
 
52
 
 
53
    void append(const E* s, size_type sz);
 
54
    
 
55
    template <class InputIterator>
 
56
    void append(InputIterator b, InputIterator e);
 
57
 
 
58
    void resize(size_type newSize, E fill);
 
59
 
 
60
    void swap(StoragePolicy& rhs);
 
61
    
 
62
    const E* c_str() const;
 
63
    const E* data() const;
 
64
    
 
65
    A get_allocator() const;
 
66
};
 
67
////////////////////////////////////////////////////////////////////////////////
 
68
*/
 
69
 
 
70
#include <memory>
 
71
#include <algorithm>
 
72
#include <functional>
 
73
#include <cassert>
 
74
#include <limits>
 
75
#include <stdexcept>
 
76
#include "flex_string_details.h"
 
77
 
 
78
 
 
79
////////////////////////////////////////////////////////////////////////////////
 
80
// class template CowStringOpt
 
81
// Implements Copy on Write over any storage
 
82
////////////////////////////////////////////////////////////////////////////////
 
83
 
 
84
template <class Storage, typename Align = typename Storage::value_type*>
 
85
class CowStringOpt
 
86
{
 
87
    typedef typename Storage::value_type E;
 
88
    typedef typename flex_string_details::get_unsigned<E>::result RefCountType;
 
89
 
 
90
public:
 
91
    typedef E value_type;
 
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;
 
97
    
 
98
private:
 
99
    union
 
100
    {
 
101
        mutable char buf_[sizeof(Storage)];
 
102
        Align align_;
 
103
    };
 
104
 
 
105
    Storage& Data() const
 
106
    { return *reinterpret_cast<Storage*>(buf_); }
 
107
 
 
108
    RefCountType GetRefs() const
 
109
    {
 
110
        const Storage& d = Data();
 
111
        assert(d.size() > 0);
 
112
        assert(*d.begin() > 0);
 
113
        return *d.begin();
 
114
    }
 
115
    
 
116
    RefCountType& Refs()
 
117
    {
 
118
        Storage& d = Data();
 
119
        assert(d.size() > 0);
 
120
        return reinterpret_cast<RefCountType&>(*d.begin());
 
121
    }
 
122
    
 
123
    void MakeUnique() const
 
124
    {
 
125
        assert(GetRefs() >= 1);
 
126
        if (GetRefs() == 1) return;
 
127
 
 
128
        union
 
129
        {
 
130
            char buf_[sizeof(Storage)];
 
131
            Align align_;
 
132
        } temp;
 
133
 
 
134
        new(buf_) Storage(
 
135
            *new(temp.buf_) Storage(Data()), 
 
136
            flex_string_details::Shallow());
 
137
        *Data().begin() = 1;
 
138
    }
 
139
 
 
140
public:
 
141
    CowStringOpt(const CowStringOpt& s)
 
142
    {
 
143
        if (s.GetRefs() == std::numeric_limits<RefCountType>::max())
 
144
        {
 
145
            // must make a brand new copy
 
146
            new(buf_) Storage(s.Data()); // non shallow
 
147
            Refs() = 1;
 
148
        }
 
149
        else
 
150
        {
 
151
            new(buf_) Storage(s.Data(), flex_string_details::Shallow());
 
152
            ++Refs();
 
153
        }
 
154
        assert(Data().size() > 0);
 
155
    }
 
156
    
 
157
    CowStringOpt(const allocator_type& a)
 
158
    {
 
159
        new(buf_) Storage(1, 1, a);
 
160
    }
 
161
    
 
162
    CowStringOpt(const E* s, size_type len, const allocator_type& a)
 
163
    {
 
164
        // Warning - MSVC's debugger has trouble tracing through the code below.
 
165
        // It seems to be a const-correctness issue
 
166
        //
 
167
        new(buf_) Storage(a);
 
168
        Data().reserve(len + 1);
 
169
        Data().resize(1, 1);
 
170
        Data().append(s, s + len);
 
171
    }
 
172
 
 
173
    CowStringOpt(size_type len, E c, const allocator_type& a)
 
174
    {
 
175
        new(buf_) Storage(len + 1, c, a);
 
176
        Refs() = 1;
 
177
    }
 
178
    
 
179
    CowStringOpt& operator=(const CowStringOpt& rhs)
 
180
    {
 
181
        CowStringOpt(rhs).swap(*this);
 
182
        return *this;
 
183
    }
 
184
 
 
185
    ~CowStringOpt()
 
186
    {
 
187
        assert(Data().size() > 0);
 
188
        if (--Refs() == 0) Data().~Storage();
 
189
    }
 
190
 
 
191
    iterator begin()
 
192
    {
 
193
        assert(Data().size() > 0);
 
194
        MakeUnique();
 
195
        return Data().begin() + 1; 
 
196
    }
 
197
    
 
198
    const_iterator begin() const
 
199
    {
 
200
        assert(Data().size() > 0);
 
201
        return Data().begin() + 1; 
 
202
    }
 
203
    
 
204
    iterator end()
 
205
    {
 
206
        MakeUnique();
 
207
        return Data().end(); 
 
208
    }
 
209
    
 
210
    const_iterator end() const
 
211
    {
 
212
        return Data().end(); 
 
213
    }
 
214
    
 
215
    size_type size() const
 
216
    {
 
217
        assert(Data().size() > 0);
 
218
        return Data().size() - 1;
 
219
    }
 
220
 
 
221
    size_type max_size() const
 
222
    { 
 
223
        assert(Data().max_size() > 0);
 
224
        return Data().max_size() - 1;
 
225
    }
 
226
 
 
227
    size_type capacity() const
 
228
    { 
 
229
        assert(Data().capacity() > 0);
 
230
        return Data().capacity() - 1;
 
231
    }
 
232
 
 
233
    void resize(size_type n, E c)
 
234
    {
 
235
        assert(Data().size() > 0);
 
236
        MakeUnique();
 
237
        Data().resize(n + 1, c);
 
238
    }
 
239
 
 
240
    template <class FwdIterator>
 
241
    void append(FwdIterator b, FwdIterator e)
 
242
    {
 
243
        MakeUnique();
 
244
        Data().append(b, e);
 
245
    }
 
246
    
 
247
    void reserve(size_type res_arg)
 
248
    {
 
249
        if (capacity() > res_arg) return;
 
250
        MakeUnique();
 
251
        Data().reserve(res_arg + 1);
 
252
    }
 
253
    
 
254
    void swap(CowStringOpt& rhs)
 
255
    {
 
256
        Data().swap(rhs.Data());
 
257
    }
 
258
    
 
259
    const E* c_str() const
 
260
    { 
 
261
        assert(Data().size() > 0);
 
262
        return Data().c_str() + 1;
 
263
    }
 
264
 
 
265
    const E* data() const
 
266
    { 
 
267
        assert(Data().size() > 0);
 
268
        return Data().data() + 1;
 
269
    }
 
270
    
 
271
    allocator_type get_allocator() const
 
272
    { 
 
273
        return Data().get_allocator();
 
274
    }
 
275
};
 
276
 
 
277
 
 
278
#endif // COW_STRING_OPT_INC_