1/*
2 * Copyright 2015 Aerospike, Inc.
3 *
4 * Portions may be licensed to Aerospike, Inc. under one or more
5 * contributor license agreements.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you
8 * may not use this file except in compliance with the License. You
9 * may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 * implied. See the License for the specific language governing
16 * permissions and limitations under the License.
17 */
18
19#ifndef scoped_h__
20#define scoped_h__
21
22template <typename T>
23class Scoped
24{
25public:
26 /// A deletion function.
27 typedef void (*Del)(T p);
28
29 /// Default constructor.
30 ///
31 /// Note - the deletion function will not be called on the nil
32 /// value.
33 ///
34 /// @param[in] i_nil Nil value.
35 /// @param[in] i_del Deletion functor.
36 ///
37 Scoped(T const & i_nil, Del i_del)
38 : m_val(i_nil)
39 , m_nil(i_nil)
40 , m_del(i_del)
41 {}
42
43 /// Contructor from value.
44 ///
45 /// Note - the deletion function will not be called on the nil
46 /// value.
47 ///
48 /// @param[in] i_val The value to assign.
49 /// @param[in] i_nil Nil value.
50 /// @param[in] i_del Deletion functor.
51 ///
52 Scoped(T const & i_val, T const & i_nil, Del i_del)
53 : m_val(i_val)
54 , m_nil(i_nil)
55 , m_del(i_del)
56 {}
57
58
59 /// Destructor, calls deletion function on non-nil values.
60 ///
61 ~Scoped()
62 {
63 if (m_val != m_nil)
64 m_del(m_val);
65 }
66
67 /// Assignment operator.
68 ///
69 /// Calls deletion on existing non-nil value and assigns new
70 /// value.
71 ///
72 /// @param[in] i_val The right-hand-side is the new value.
73 ///
74 inline Scoped & operator=(T const & i_val)
75 {
76 // Delete any pre-existing value.
77 if (m_val != m_nil)
78 m_del(m_val);
79
80 m_val = i_val;
81 return *this;
82 }
83
84 /// Pointer dereference.
85 ///
86 inline T const operator->() const { return m_val; }
87
88 /// Reference.
89 ///
90 inline operator T&() { return m_val; }
91
92 /// Takes value, will not be deleted.
93 ///
94 T const take()
95 {
96 T tmp = m_val;
97 m_val = m_nil;
98 return tmp;
99 }
100
101private:
102 T m_val;
103 T m_nil;
104 Del m_del;
105};
106
107#endif // scoped_h__
108