tmpI.H 7.36 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

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

template<class T>
Mark Olesen's avatar
Mark Olesen committed
32
inline Foam::tmp<T>::tmp(T* tPtr)
33
:
34
35
    type_(TMP),
    ptr_(tPtr)
36
37
38
39
40
41
42
43
44
{
    if (tPtr && !tPtr->unique())
    {
        FatalErrorInFunction
            << "Attempted construction of a " << typeName()
            << " from non-unique pointer"
            << abort(FatalError);
    }
}
45
46


47
template<class T>
Mark Olesen's avatar
Mark Olesen committed
48
inline Foam::tmp<T>::tmp(const T& tRef)
49
:
50
51
    type_(CONST_REF),
    ptr_(const_cast<T*>(&tRef))
52
53
54
55
{}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
56
inline Foam::tmp<T>::tmp(const tmp<T>& t)
57
:
58
59
    type_(t.type_),
    ptr_(t.ptr_)
60
{
61
    if (isTmp())
62
63
64
65
66
67
68
    {
        if (ptr_)
        {
            ptr_->operator++();
        }
        else
        {
69
            FatalErrorInFunction
70
                << "Attempted copy of a deallocated " << typeName()
71
72
73
74
75
76
                << abort(FatalError);
        }
    }
}


77
78
79
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
:
80
81
    type_(t.type_),
    ptr_(t.ptr_)
82
{
83
    if (isTmp())
84
    {
85
        if (ptr_)
86
        {
87
            if (allowTransfer)
88
            {
89
                t.ptr_ = 0;
90
91
92
            }
            else
            {
93
                ptr_->operator++();
94
95
            }
        }
96
97
98
99
100
101
        else
        {
            FatalErrorInFunction
                << "Attempted copy of a deallocated " << typeName()
                << abort(FatalError);
        }
102
103
104
105
    }
}


106
template<class T>
Mark Olesen's avatar
Mark Olesen committed
107
inline Foam::tmp<T>::~tmp()
108
{
109
    clear();
110
111
112
113
114
115
}


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

template<class T>
Mark Olesen's avatar
Mark Olesen committed
116
inline bool Foam::tmp<T>::isTmp() const
117
{
118
    return type_ == TMP;
119
120
121
}


122
123
124
template<class T>
inline bool Foam::tmp<T>::empty() const
{
125
    return (isTmp() && !ptr_);
126
127
128
}


129
template<class T>
Mark Olesen's avatar
Mark Olesen committed
130
inline bool Foam::tmp<T>::valid() const
131
{
132
133
134
135
    return (!isTmp() || (isTmp() && ptr_));
}


136
137
138
139
140
141
142
template<class T>
inline Foam::word Foam::tmp<T>::typeName() const
{
    return "tmp<" + word(typeid(T).name()) + '>';
}


143
144
145
template<class T>
inline T& Foam::tmp<T>::ref()
{
146
    if (isTmp())
147
148
149
150
    {
        if (!ptr_)
        {
            FatalErrorInFunction
151
                << typeName() << " deallocated"
152
153
154
155
156
                << abort(FatalError);
        }
    }
    else
    {
157
158
        FatalErrorInFunction
            << "Attempt to acquire non-const reference to const object"
159
            << " from a " << typeName()
160
161
            << abort(FatalError);
    }
162
163

    return *ptr_;
164
165
166
167
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
168
inline T* Foam::tmp<T>::ptr() const
169
{
170
    if (isTmp())
171
    {
172
173
174
        if (!ptr_)
        {
            FatalErrorInFunction
175
                << typeName() << " deallocated"
176
177
                << abort(FatalError);
        }
178

179
180
181
182
        if (!ptr_->unique())
        {
            FatalErrorInFunction
                << "Attempt to acquire pointer to object referred to"
183
                << " by multiple temporaries of type " << typeName()
184
185
                << abort(FatalError);
        }
186

187
188
        T* ptr = ptr_;
        ptr_ = 0;
189

190
        return ptr;
191
192
193
    }
    else
    {
194
        return new T(*ptr_);
195
196
197
198
199
    }
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
200
inline void Foam::tmp<T>::clear() const
201
{
202
    if (isTmp() && ptr_)
203
    {
204
205
206
207
208
209
210
211
212
213
        if (ptr_->unique())
        {
            delete ptr_;
            ptr_ = 0;
        }
        else
        {
            ptr_->operator--();
            ptr_ = 0;
        }
214
215
216
217
218
219
    }
}


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

220
#ifndef CONST_TMP
221
template<class T>
Mark Olesen's avatar
Mark Olesen committed
222
inline T& Foam::tmp<T>::operator()()
223
{
224
    if (isTmp())
225
226
227
    {
        if (!ptr_)
        {
228
            FatalErrorInFunction
229
                << typeName() << " deallocated"
230
231
232
                << abort(FatalError);
        }
    }
233
234
235
236

    // Const-ness is automatically cast-away which is why this operator is
    // deprecated.  Use ref() where non-const access is required.
    return *ptr_;
237
}
238
#endif
239
240
241


template<class T>
Mark Olesen's avatar
Mark Olesen committed
242
inline const T& Foam::tmp<T>::operator()() const
243
{
244
    if (isTmp())
245
246
247
    {
        if (!ptr_)
        {
248
            FatalErrorInFunction
249
                << typeName() << " deallocated"
250
251
252
                << abort(FatalError);
        }
    }
253
254
255

    // Return const reference
    return *ptr_;
256
257
258
259
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
260
inline Foam::tmp<T>::operator const T&() const
261
262
263
264
265
266
{
    return operator()();
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
267
inline T* Foam::tmp<T>::operator->()
268
{
269
    if (isTmp())
270
    {
271
272
273
274
275
276
        if (!ptr_)
        {
            FatalErrorInFunction
                << typeName() << " deallocated"
                << abort(FatalError);
        }
277
278
279
    }
    else
    {
280
281
        FatalErrorInFunction
            << "Attempt to cast const object to non-const for a " << typeName()
282
            << abort(FatalError);
283
    }
284
285

    return ptr_;
286
287
288
289
}


template<class T>
Mark Olesen's avatar
Mark Olesen committed
290
inline const T* Foam::tmp<T>::operator->() const
291
{
292
    if (isTmp() && !ptr_)
293
    {
294
295
296
        FatalErrorInFunction
            << typeName() << " deallocated"
            << abort(FatalError);
297
    }
298
299

    return ptr_;
300
301
302
303
}


template<class T>
304
inline void Foam::tmp<T>::operator=(T* tPtr)
305
{
306
307
308
    clear();

    if (!tPtr)
309
    {
310
311
312
        FatalErrorInFunction
            << "Attempted copy of a deallocated " << typeName()
            << abort(FatalError);
313
314
    }

315
    if (tPtr && !tPtr->unique())
316
    {
317
        FatalErrorInFunction
318
319
            << "Attempted assignment of a " << typeName()
            << " to non-unique pointer"
320
321
            << abort(FatalError);
    }
322

323
    type_ = TMP;
324
325
326
327
328
329
330
    ptr_ = tPtr;
}


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

333
    if (t.isTmp())
334
    {
335
        type_ = TMP;
336
337

        if (!t.ptr_)
338
        {
339
            FatalErrorInFunction
340
                << "Attempted assignment to a deallocated " << typeName()
341
342
                << abort(FatalError);
        }
343
344

        ptr_ = t.ptr_;
345
346

        ptr_->operator++();
347
348
349
    }
    else
    {
350
        FatalErrorInFunction
351
            << "Attempted assignment to a const reference to an object"
352
            << " of type " << typeid(T).name()
353
354
355
356
357
            << abort(FatalError);
    }
}


358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
//- Return the const reference of the non-const reference argument
template<typename T>
inline const T& Const(T& t)
{
    return t;
}


//- Return the const reference of the non-const rvalue reference argument
template<typename T>
inline const T& Const(T&& t)
{
    return t;
}


374
// ************************************************************************* //