Branch data Line data Source code
1 : : /********************************************************************\
2 : : * kvp-value.hpp -- Implements a key-value frame system *
3 : : * Copyright (C) 2014 Aaron Laws *
4 : : * *
5 : : * This program is free software; you can redistribute it and/or *
6 : : * modify it under the terms of the GNU General Public License as *
7 : : * published by the Free Software Foundation; either version 2 of *
8 : : * the License, or (at your option) any later version. *
9 : : * *
10 : : * This program is distributed in the hope that it will be useful, *
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 : : * GNU General Public License for more details. *
14 : : * *
15 : : * You should have received a copy of the GNU General Public License*
16 : : * along with this program; if not, contact: *
17 : : * *
18 : : * Free Software Foundation Voice: +1-617-542-5942 *
19 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20 : : * Boston, MA 02110-1301, USA gnu@gnu.org *
21 : : * *
22 : : \********************************************************************/
23 : :
24 : : #ifndef GNC_KVP_VALUE_TYPE
25 : : #define GNC_KVP_VALUE_TYPE
26 : :
27 : : #include <config.h>
28 : : #include "qof.h"
29 : :
30 : : #include <cstdint>
31 : : #include <boost/variant.hpp>
32 : :
33 : : //Must be a struct because it's exposed to C so that it can in turn be
34 : : //translated to/from Scheme.
35 : : /** @addtogroup KVP
36 : : * @{
37 : : */
38 : :
39 : : /** Implements KvpValue using boost::variant. Capable of holding the following
40 : : * types:
41 : : * * int64_t
42 : : * * double
43 : : * * gnc_numeric
44 : : * * const char*
45 : : * * GncGUID*
46 : : * * Timepsec
47 : : * * GList*
48 : : * * KvpFrame*
49 : : * * GDate
50 : : */
51 : :
52 : : struct KvpValueImpl
53 : : {
54 : : public:
55 : : enum Type
56 : : {
57 : : INVALID = -1,
58 : : INT64 = 1, /**< QOF_TYPE_INT64 gint64 */
59 : : DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */
60 : : NUMERIC, /**< QOF_TYPE_NUMERIC */
61 : : STRING, /**< QOF_TYPE_STRING gchar* */
62 : : GUID, /**< QOF_TYPE_GUID */
63 : : TIME64, /**< QOF_TYPE_DATE */
64 : : PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */
65 : : GLIST, /**< no QOF equivalent. */
66 : : FRAME, /**< no QOF equivalent. */
67 : : GDATE, /**< no QOF equivalent. */
68 : : };
69 : :
70 : : /**
71 : : * Performs a deep copy
72 : : */
73 : : KvpValueImpl(KvpValueImpl const &) noexcept;
74 : : KvpValueImpl& operator=(const KvpValueImpl&) noexcept;
75 : :
76 : : /**
77 : : * Move. The old object's datastore is set to int64_t 0.
78 : : */
79 : : KvpValueImpl(KvpValueImpl && b) noexcept;
80 : : KvpValueImpl& operator=(KvpValueImpl && b) noexcept;
81 : :
82 : : /** Create a KvpValue containing the passed in item. Note that for pointer
83 : : * types const char*, KvpFrame*, GncGUID*, and GList* the KvpValue takes
84 : : * ownership of the object and will delete/free it when the KvpValue is
85 : : * destroyed. That means these objects must be allocated in the free store
86 : : * or heap as follows:
87 : : * * const char*: GLib string allocation, e.g. g_strdup()/
88 : : * * KvpFrame*: operator new
89 : : * * GncGUID*: guid_new() or guid_copy()
90 : : * * GList*: Uses g_list_free(), so it's up to classes using this to empty
91 : : the list before destroying the KvpValue.
92 : : */
93 : :
94 : : template <typename T>
95 : : KvpValueImpl(T) noexcept;
96 : :
97 : : /**
98 : : * Performs a deep delete.
99 : : *
100 : : * The contents of this KvpValueImpl are also deleted.
101 : : */
102 : : ~KvpValueImpl() noexcept;
103 : :
104 : : /**
105 : : * Adds another value to this KvpValueImpl.
106 : : *
107 : : * If this KvpValueImpl represents a collection (GList),
108 : : * the new value is added to the collection and this
109 : : * is returned.
110 : : *
111 : : * Otherwise, a new KvpValueImpl representing a collection
112 : : * is created, this and the new value are added to it,
113 : : * and it is returned.
114 : : */
115 : : KvpValueImpl * add (KvpValueImpl *) noexcept;
116 : :
117 : : KvpValueImpl::Type get_type() const noexcept;
118 : :
119 : : std::string to_string() const noexcept;
120 : : std::string to_string(std::string const & prefix) const noexcept;
121 : :
122 : : template <typename T>
123 : : T get() const noexcept;
124 : : template <typename T>
125 : : const T* get_ptr() const noexcept;
126 : :
127 : : template <typename T>
128 : : void set(T) noexcept;
129 : :
130 : : friend int compare(const KvpValueImpl &, const KvpValueImpl &) noexcept;
131 : :
132 : : private:
133 : : void duplicate(const KvpValueImpl&) noexcept;
134 : : boost::variant<
135 : : int64_t,
136 : : double,
137 : : gnc_numeric,
138 : : const char*,
139 : : GncGUID *,
140 : : Time64,
141 : : GList *,
142 : : KvpFrame *,
143 : : GDate> datastore;
144 : : };
145 : :
146 : : int
147 : : compare(const KvpValueImpl *, const KvpValue *) noexcept;
148 : : /** @} Close Doxygen AddToGroup */
149 : : template <typename T>
150 : 4815 : KvpValueImpl::KvpValueImpl(T newvalue) noexcept:
151 : 4815 : datastore(newvalue)
152 : : {
153 : 4815 : }
154 : :
155 : : template <typename T> T
156 : 14931 : KvpValueImpl::get() const noexcept
157 : : {
158 : 14931 : if (this->datastore.type() != boost::typeindex::type_id<T>()) return {};
159 : 14866 : return boost::get<T>(datastore);
160 : : }
161 : :
162 : : template <typename T> const T*
163 : 158 : KvpValueImpl::get_ptr() const noexcept
164 : : {
165 : 158 : if (this->datastore.type() != typeid(T)) return nullptr;
166 : 158 : return boost::get<T>(&datastore);
167 : : }
168 : :
169 : : template <typename T> void
170 : 0 : KvpValueImpl::set(T val) noexcept
171 : : {
172 : 0 : this->datastore = val;
173 : 0 : }
174 : : /** @ingroup KVP
175 : : @{ */
176 : : /** @internal @{ */
177 : : /** Convert a kvp_value into a GValue. Frames aren't converted.
178 : : * @param kval: A KvpValue.
179 : : * @param val: The GValue in which to store the converted value.
180 : : */
181 : : void gvalue_from_kvp_value (const KvpValue *kval, GValue* val);
182 : :
183 : : /** Convert a gvalue into a kvpvalue.
184 : : * @param gval: A GValue of a type KvpValue can digest.
185 : : * @return KvpValue created from the GValue's contents.
186 : : */
187 : : KvpValue* kvp_value_from_gvalue (const GValue *gval);
188 : :
189 : : /** @} Close Doxygen Internal */
190 : : /** @} Close Doxygen Group */
191 : :
192 : : #endif
|