tmpI.H 7.88 KB
Newer Older
1
/*--------------------------------------------------------------------r-------*\
2
3
4
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
6
7
8
9
10
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
15
16
17
18
19
20
21

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
22
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
23
24
25
26

\*---------------------------------------------------------------------------*/

#include "error.H"
27
#include <typeinfo>
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// * * * * * * * * * * * * * Private Member Operators  * * * * * * * * * * * //

template<class T>
inline void Foam::tmp<T>::operator++()
{
    ptr_->operator++();

    if (ptr_->count() > 1)
    {
        FatalErrorInFunction
            << "Attempt to create more than 2 tmp's referring to"
               " the same object of type " << typeName()
            << abort(FatalError);
    }
}


46
47
48
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

template<class T>
Mark Olesen's avatar
Mark Olesen committed
49
inline Foam::tmp<T>::tmp(T* tPtr)
50
:
51
52
    type_(TMP),
    ptr_(tPtr)
53
54
55
56
57
58
59
60
61
{
    if (tPtr && !tPtr->unique())
    {
        FatalErrorInFunction
            << "Attempted construction of a " << typeName()
            << " from non-unique pointer"
            << abort(FatalError);
    }
}
62
63


64
template<class T>
Mark Olesen's avatar
Mark Olesen committed
65
inline Foam::tmp<T>::tmp(const T& tRef)
66
:
67
68
    type_(CONST_REF),
    ptr_(const_cast<T*>(&tRef))
69
70
71
72
{}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
73
inline Foam::tmp<T>::tmp(const tmp<T>& t)
74
:
75
76
    type_(t.type_),
    ptr_(t.ptr_)
77
{
78
    if (isTmp())
79
80
81
    {
        if (ptr_)
        {
82
            operator++();
83
84
85
        }
        else
        {
86
            FatalErrorInFunction
87
                << "Attempted copy of a deallocated " << typeName()
88
89
90
91
92
93
                << abort(FatalError);
        }
    }
}


94
95
96
97
98
99
100
101
102
103
104
105
106
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>&& t)
:
    type_(t.type_),
    ptr_(t.ptr_)
{
    if (isTmp())
    {
        t.ptr_ = 0;
    }
}


107
108
109
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
:
110
111
    type_(t.type_),
    ptr_(t.ptr_)
112
{
113
    if (isTmp())
114
    {
115
        if (ptr_)
116
        {
117
            if (allowTransfer)
118
            {
119
                t.ptr_ = 0;
120
121
122
            }
            else
            {
123
                operator++();
124
125
            }
        }
126
127
128
129
130
131
        else
        {
            FatalErrorInFunction
                << "Attempted copy of a deallocated " << typeName()
                << abort(FatalError);
        }
132
133
134
135
    }
}


136
template<class T>
Mark Olesen's avatar
Mark Olesen committed
137
inline Foam::tmp<T>::~tmp()
138
{
139
    clear();
140
141
142
143
144
145
}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

template<class T>
Mark Olesen's avatar
Mark Olesen committed
146
inline bool Foam::tmp<T>::isTmp() const
147
{
148
    return type_ == TMP;
149
150
151
}


152
153
154
template<class T>
inline bool Foam::tmp<T>::empty() const
{
155
    return (isTmp() && !ptr_);
156
157
158
}


159
template<class T>
Mark Olesen's avatar
Mark Olesen committed
160
inline bool Foam::tmp<T>::valid() const
161
{
162
163
164
165
    return (!isTmp() || (isTmp() && ptr_));
}


166
167
168
169
170
171
172
template<class T>
inline Foam::word Foam::tmp<T>::typeName() const
{
    return "tmp<" + word(typeid(T).name()) + '>';
}


173
template<class T>
174
inline T& Foam::tmp<T>::ref() const
175
{
176
    if (isTmp())
177
178
179
180
    {
        if (!ptr_)
        {
            FatalErrorInFunction
181
                << typeName() << " deallocated"
182
183
184
185
186
                << abort(FatalError);
        }
    }
    else
    {
187
188
        FatalErrorInFunction
            << "Attempt to acquire non-const reference to const object"
189
            << " from a " << typeName()
190
191
            << abort(FatalError);
    }
192
193

    return *ptr_;
194
195
196
197
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
198
inline T* Foam::tmp<T>::ptr() const
199
{
200
    if (isTmp())
201
    {
202
203
204
        if (!ptr_)
        {
            FatalErrorInFunction
205
                << typeName() << " deallocated"
206
207
                << abort(FatalError);
        }
208

209
210
211
212
        if (!ptr_->unique())
        {
            FatalErrorInFunction
                << "Attempt to acquire pointer to object referred to"
213
                << " by multiple temporaries of type " << typeName()
214
215
                << abort(FatalError);
        }
216

217
218
        T* ptr = ptr_;
        ptr_ = 0;
219

220
        return ptr;
221
222
223
    }
    else
    {
224
        return new T(*ptr_);
225
226
227
228
229
    }
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
230
inline void Foam::tmp<T>::clear() const
231
{
232
    if (isTmp() && ptr_)
233
    {
234
235
236
237
238
239
240
241
242
243
        if (ptr_->unique())
        {
            delete ptr_;
            ptr_ = 0;
        }
        else
        {
            ptr_->operator--();
            ptr_ = 0;
        }
244
245
246
247
248
249
    }
}


// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //

250
#ifdef NON_CONST_TMP
251
template<class T>
Mark Olesen's avatar
Mark Olesen committed
252
inline T& Foam::tmp<T>::operator()()
253
{
254
    if (isTmp())
255
256
257
    {
        if (!ptr_)
        {
258
            FatalErrorInFunction
259
                << typeName() << " deallocated"
260
261
262
                << abort(FatalError);
        }
    }
263
264
265
266

    // Const-ness is automatically cast-away which is why this operator is
    // deprecated.  Use ref() where non-const access is required.
    return *ptr_;
267
}
268
#endif
269
270
271


template<class T>
Mark Olesen's avatar
Mark Olesen committed
272
inline const T& Foam::tmp<T>::operator()() const
273
{
274
    if (isTmp())
275
276
277
    {
        if (!ptr_)
        {
278
            FatalErrorInFunction
279
                << typeName() << " deallocated"
280
281
282
                << abort(FatalError);
        }
    }
283
284
285

    // Return const reference
    return *ptr_;
286
287
288
289
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
290
inline Foam::tmp<T>::operator const T&() const
291
292
293
294
295
296
{
    return operator()();
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
297
inline T* Foam::tmp<T>::operator->()
298
{
299
    if (isTmp())
300
    {
301
302
303
304
305
306
        if (!ptr_)
        {
            FatalErrorInFunction
                << typeName() << " deallocated"
                << abort(FatalError);
        }
307
308
309
    }
    else
    {
310
311
        FatalErrorInFunction
            << "Attempt to cast const object to non-const for a " << typeName()
312
            << abort(FatalError);
313
    }
314
315

    return ptr_;
316
317
318
319
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
320
inline const T* Foam::tmp<T>::operator->() const
321
{
322
    if (isTmp() && !ptr_)
323
    {
324
325
326
        FatalErrorInFunction
            << typeName() << " deallocated"
            << abort(FatalError);
327
    }
328
329

    return ptr_;
330
331
332
333
}


template<class T>
334
inline void Foam::tmp<T>::operator=(T* tPtr)
335
{
336
337
338
    clear();

    if (!tPtr)
339
    {
340
341
342
        FatalErrorInFunction
            << "Attempted copy of a deallocated " << typeName()
            << abort(FatalError);
343
344
    }

345
    if (tPtr && !tPtr->unique())
346
    {
347
        FatalErrorInFunction
348
349
            << "Attempted assignment of a " << typeName()
            << " to non-unique pointer"
350
351
            << abort(FatalError);
    }
352

353
    type_ = TMP;
354
355
356
357
358
359
360
    ptr_ = tPtr;
}


template<class T>
inline void Foam::tmp<T>::operator=(const tmp<T>& t)
{
361
    clear();
362

363
    if (t.isTmp())
364
    {
365
        type_ = TMP;
366
367

        if (!t.ptr_)
368
        {
369
            FatalErrorInFunction
370
                << "Attempted assignment to a deallocated " << typeName()
371
372
                << abort(FatalError);
        }
373
374

        ptr_ = t.ptr_;
375
        t.ptr_ = 0;
376
377
378
    }
    else
    {
379
        FatalErrorInFunction
380
            << "Attempted assignment to a const reference to an object"
381
            << " of type " << typeid(T).name()
382
383
384
385
386
            << abort(FatalError);
    }
}


387
//- Return the const reference of the non-const reference argument
388
template<class T>
389
390
391
392
393
394
395
inline const T& Const(T& t)
{
    return t;
}


//- Return the const reference of the non-const rvalue reference argument
396
template<class T>
397
398
399
400
401
402
inline const T& Const(T&& t)
{
    return t;
}


403
// ************************************************************************* //