xrpld
Loading...
Searching...
No Matches
KnownFormats.h
1#pragma once
2
3#include <xrpl/basics/contract.h>
4#include <xrpl/beast/type_name.h>
5#include <xrpl/protocol/SOTemplate.h>
6
7#include <boost/container/flat_map.hpp>
8
9#include <algorithm>
10#include <cstddef>
11#include <forward_list>
12#include <stdexcept>
13#include <utility>
14#include <vector>
15
16namespace xrpl {
17
26template <class KeyType, class Derived>
28{
29public:
33 class Item
34 {
35 public:
37 char const* name,
38 KeyType type,
39 std::vector<SOElement> uniqueFields,
40 std::vector<SOElement> commonFields)
41 : soTemplate_(std::move(uniqueFields), std::move(commonFields))
42 , name_(name)
43 , type_(type)
44 {
45 // Verify that KeyType is appropriate.
46 static_assert(
48 "KnownFormats KeyType must be integral or enum.");
49 }
50
54 [[nodiscard]] std::string const&
55 getName() const
56 {
57 return name_;
58 }
59
63 [[nodiscard]] KeyType
64 getType() const
65 {
66 return type_;
67 }
68
69 [[nodiscard]] SOTemplate const&
71 {
72 return soTemplate_;
73 }
74
75 private:
79 };
80
86private:
87 KnownFormats() : name_(beast::typeName<Derived>())
88 {
89 }
90
91public:
97 virtual ~KnownFormats() = default;
98 KnownFormats(KnownFormats const&) = delete;
100 operator=(KnownFormats const&) = delete;
101
110 [[nodiscard]] KeyType
111 findTypeByName(std::string const& name) const
112 {
113 if (auto const result = findByName(name))
114 return result->getType();
116 name_ + ": Unknown format name '" +
117 name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
118 }
119
123 [[nodiscard]] Item const*
124 findByType(KeyType type) const
125 {
126 auto const itr = types_.find(type);
127 if (itr == types_.end())
128 return nullptr;
129 return itr->second;
130 }
131
132 // begin() and end() are provided for testing purposes.
133 [[nodiscard]] std::forward_list<Item>::const_iterator
134 begin() const
135 {
136 return formats_.begin();
137 }
138
139 [[nodiscard]] std::forward_list<Item>::const_iterator
140 end() const
141 {
142 return formats_.end();
143 }
144
145protected:
149 [[nodiscard]] Item const*
150 findByName(std::string const& name) const
151 {
152 auto const itr = names_.find(name);
153 if (itr == names_.end())
154 return nullptr;
155 return itr->second;
156 }
157
168 Item const&
169 add(char const* name,
170 KeyType type,
171 std::vector<SOElement> uniqueFields,
172 std::vector<SOElement> commonFields = {})
173 {
174 if (auto const item = findByType(type))
175 {
177 std::string("Duplicate key for item '") + name + "': already maps to " +
178 item->getName());
179 }
180
181 formats_.emplace_front(name, type, std::move(uniqueFields), std::move(commonFields));
182 Item const& item{formats_.front()};
183
184 names_[name] = &item;
185 types_[type] = &item;
186
187 return item;
188 }
189
190private:
192
193 // One of the situations where a std::forward_list is useful. We want to
194 // store each Item in a place where its address won't change. So a node-
195 // based container is appropriate. But we don't need searchability.
197
198 boost::container::flat_map<std::string, Item const*> names_{};
199 boost::container::flat_map<KeyType, Item const*> types_{};
200 friend Derived;
201};
202
203} // namespace xrpl
KeyType getType() const
Retrieve the transaction type this format represents.
Item(char const *name, KeyType type, std::vector< SOElement > uniqueFields, std::vector< SOElement > commonFields)
SOTemplate const & getSOTemplate() const
std::string const name_
std::string const & getName() const
Retrieve the name of the format.
virtual ~KnownFormats()=default
Destroy the known formats object.
KnownFormats()
Create the known formats object.
KnownFormats & operator=(KnownFormats const &)=delete
std::forward_list< Item >::const_iterator end() const
KnownFormats(KnownFormats const &)=delete
Item const & add(char const *name, KeyType type, std::vector< SOElement > uniqueFields, std::vector< SOElement > commonFields={})
Add a new format.
std::forward_list< Item > formats_
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Item const * findByName(std::string const &name) const
Retrieve a format based on its name.
std::forward_list< Item >::const_iterator begin() const
boost::container::flat_map< KeyType, Item const * > types_
boost::container::flat_map< std::string, Item const * > names_
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:105
T is_enum_v
T is_integral_v
T min(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
KeyType
Definition KeyType.h:8
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T size(T... args)
T substr(T... args)