GnuCash  5.6-150-g038405b370+
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>
94 using Path = std::vector<std::string>;
95 using 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 
241 template<typename func_type, typename data_type>
242 void 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 
255 template <typename func_type>
256 void 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 
266 template <typename func_type, typename data_type>
267 void 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 
277 int compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept;
278 int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept;
281 #endif
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...
~KvpFrameImpl() noexcept
Perform a deep delete.
Definition: kvp-frame.cpp:54
Implements KvpFrame.
Definition: kvp-frame.hpp:109
STL namespace.
std::string to_string() const noexcept
Make a string representation of the frame.
Definition: kvp-frame.cpp:157
std::vector< KvpEntry > flatten_kvp(void) const noexcept
Returns all keys and values of this frame recursively, flattening the frame-containing values...
KvpValue * set(Path path, KvpValue *newvalue) noexcept
Set the value with the key in the immediate frame, replacing and returning the old value if it exists...
Definition: kvp-frame.cpp:119
bool empty() const noexcept
Test for emptiness.
Definition: kvp-frame.hpp:226
void for_each_slot_prefix(std::string const &prefix, func_type const &, data_type &) const noexcept
Like for_each_slot, but doesn&#39;t traverse nested values.
friend int compare(const KvpFrameImpl &, const KvpFrameImpl &) noexcept
If the first KvpFrameImpl has an item that the second does not, 1 is returned.
Definition: kvp-frame.cpp:215
std::vector< std::string > get_keys() const noexcept
Report the keys in the immediate frame.
Definition: kvp-frame.cpp:187
KvpValue * get_slot(Path keys) noexcept
Get the value for the tail of the path or nullptr if it doesn&#39;t exist.
Definition: kvp-frame.cpp:143
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 ...
Definition: kvp-frame.cpp:132