GnuCash c935c2f+
Loading...
Searching...
No Matches
kvp-frame.hpp
1/********************************************************************\
2 * kvp-frame.hpp -- Implements a key-value frame system *
3 * Copyright (C) 2014 Aaron Laws *
4 * Copyright 2015 John Ralls *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License*
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22 * *
23\********************************************************************/
84#ifndef GNC_KVP_FRAME_TYPE
85#define GNC_KVP_FRAME_TYPE
86
87#include "kvp-value.hpp"
88#include <map>
89#include <string>
90#include <vector>
91#include <cstring>
92#include <algorithm>
93#include <iostream>
94using Path = std::vector<std::string>;
95using KvpEntry = std::pair <std::vector <std::string>, KvpValue*>;
96
110{
112 {
113 public:
114 /* Returns true if one is less than two. */
115 bool operator()(const char * one, const char * two) const
116 {
117 auto ret = std::strcmp(one, two) < 0;
118 return ret;
119 }
120 };
121 using map_type = std::map<const char *, KvpValue*, cstring_comparer>;
122
123 public:
124 KvpFrameImpl() noexcept {};
125
129 KvpFrameImpl(const KvpFrameImpl &) noexcept;
130
134 ~KvpFrameImpl() noexcept;
135
145 //KvpValue* set(const char * key, KvpValue* newvalue) noexcept;
159 KvpValue* set(Path path, KvpValue* newvalue) noexcept;
171 KvpValue* set_path(Path path, KvpValue* newvalue) noexcept;
176 std::string to_string() const noexcept;
182 std::string to_string(std::string const &) const noexcept;
188 std::vector<std::string> get_keys() const noexcept;
189
194 KvpValue* get_slot(Path keys) noexcept;
195
200 template <typename func_type, typename data_type>
201 void for_each_slot_temp(func_type const &, data_type &) const noexcept;
202
203 template <typename func_type>
204 void for_each_slot_temp(func_type const &) const noexcept;
205
210 template <typename func_type, typename data_type>
211 void for_each_slot_prefix(std::string const & prefix, func_type const &, data_type &) const noexcept;
212
213 template <typename func_type>
214 void for_each_slot_prefix(std::string const & prefix, func_type const &) const noexcept;
215
220 std::vector <KvpEntry>
221 flatten_kvp(void) const noexcept;
222
226 bool empty() const noexcept { return m_valuemap.empty(); }
227 friend int compare(const KvpFrameImpl&, const KvpFrameImpl&) noexcept;
228
229 map_type::iterator begin() { return m_valuemap.begin(); }
230 map_type::iterator end() { return m_valuemap.end(); }
231
232 private:
233 map_type m_valuemap;
234
235 KvpFrame * get_child_frame_or_nullptr (Path const &) noexcept;
236 KvpFrame * get_child_frame_or_create (Path const &) noexcept;
237 void flatten_kvp_impl(std::vector <std::string>, std::vector <KvpEntry> &) const noexcept;
238 KvpValue * set_impl (std::string const &, KvpValue *) noexcept;
239};
240
241template<typename func_type, typename data_type>
242void KvpFrame::for_each_slot_prefix(std::string const & prefix,
243 func_type const & func, data_type & data) const noexcept
244{
245 std::for_each (m_valuemap.begin(), m_valuemap.end(),
246 [&prefix,&func,&data](const KvpFrameImpl::map_type::value_type & a)
247 {
248 /* Testing for prefix matching */
249 if (strncmp(a.first, prefix.c_str(), prefix.size()) == 0)
250 func (&a.first[prefix.size()], a.second, data);
251 }
252 );
253}
254
255template <typename func_type>
256void KvpFrame::for_each_slot_temp(func_type const & func) const noexcept
257{
258 std::for_each (m_valuemap.begin(), m_valuemap.end(),
259 [&func](const KvpFrameImpl::map_type::value_type & a)
260 {
261 func (a.first, a.second);
262 }
263 );
264}
265
266template <typename func_type, typename data_type>
267void KvpFrame::for_each_slot_temp(func_type const & func, data_type & data) const noexcept
268{
269 std::for_each (m_valuemap.begin(), m_valuemap.end(),
270 [&func,&data](const KvpFrameImpl::map_type::value_type & a)
271 {
272 func (a.first, a.second, data);
273 }
274 );
275}
276
277int compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept;
278int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept;
281#endif
std::vector< std::string > get_keys() const noexcept
Report the keys in the immediate frame.
~KvpFrameImpl() noexcept
Perform a deep delete.
Definition kvp-frame.cpp:55
std::vector< KvpEntry > flatten_kvp(void) const noexcept
Returns all keys and values of this frame recursively, flattening the frame-containing values.
std::string to_string() const noexcept
Make a string representation of the frame.
void for_each_slot_prefix(std::string const &prefix, func_type const &, data_type &) const noexcept
Like for_each_slot, but doesn't traverse nested values.
bool empty() const noexcept
Test for emptiness.
KvpValue * get_slot(Path keys) noexcept
Get the value for the tail of the path or nullptr if it doesn't exist.
friend int compare(const KvpFrameImpl &, const KvpFrameImpl &) noexcept
If the first KvpFrameImpl has an item that the second does not, 1 is returned.
KvpValue * set_path(Path path, KvpValue *newvalue) noexcept
Set the value with the key in a subframe following the keys in path, replacing and returning the old ...
void for_each_slot_temp(func_type const &, data_type &) const noexcept
The function should be of the form: <anything> func (char const *, KvpValue *, data_type &); Do not p...
Implements KvpFrame.