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 <forward_list>
11
12namespace xrpl {
13
21template <class KeyType, class Derived>
23{
24public:
27 class Item
28 {
29 public:
31 char const* name,
32 KeyType type,
33 std::vector<SOElement> uniqueFields,
34 std::vector<SOElement> commonFields)
35 : soTemplate_(std::move(uniqueFields), std::move(commonFields))
36 , name_(name)
37 , type_(type)
38 {
39 // Verify that KeyType is appropriate.
40 static_assert(
42 "KnownFormats KeyType must be integral or enum.");
43 }
44
47 [[nodiscard]] std::string const&
48 getName() const
49 {
50 return name_;
51 }
52
55 [[nodiscard]] KeyType
56 getType() const
57 {
58 return type_;
59 }
60
61 [[nodiscard]] SOTemplate const&
63 {
64 return soTemplate_;
65 }
66
67 private:
71 };
72
77private:
78 KnownFormats() : name_(beast::typeName<Derived>())
79 {
80 }
81
82public:
87 virtual ~KnownFormats() = default;
88 KnownFormats(KnownFormats const&) = delete;
90 operator=(KnownFormats const&) = delete;
91
99 [[nodiscard]] KeyType
100 findTypeByName(std::string const& name) const
101 {
102 if (auto const result = findByName(name))
103 return result->getType();
105 name_ + ": Unknown format name '" +
106 name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
107 }
108
111 [[nodiscard]] Item const*
112 findByType(KeyType type) const
113 {
114 auto const itr = types_.find(type);
115 if (itr == types_.end())
116 return nullptr;
117 return itr->second;
118 }
119
120 // begin() and end() are provided for testing purposes.
121 [[nodiscard]] std::forward_list<Item>::const_iterator
122 begin() const
123 {
124 return formats_.begin();
125 }
126
127 [[nodiscard]] std::forward_list<Item>::const_iterator
128 end() const
129 {
130 return formats_.end();
131 }
132
133protected:
136 [[nodiscard]] Item const*
137 findByName(std::string const& name) const
138 {
139 auto const itr = names_.find(name);
140 if (itr == names_.end())
141 return nullptr;
142 return itr->second;
143 }
144
154 Item const&
155 add(char const* name,
156 KeyType type,
157 std::vector<SOElement> uniqueFields,
158 std::vector<SOElement> commonFields = {})
159 {
160 if (auto const item = findByType(type))
161 {
163 std::string("Duplicate key for item '") + name + "': already maps to " +
164 item->getName());
165 }
166
167 formats_.emplace_front(name, type, std::move(uniqueFields), std::move(commonFields));
168 Item const& item{formats_.front()};
169
170 names_[name] = &item;
171 types_[type] = &item;
172
173 return item;
174 }
175
176private:
178
179 // One of the situations where a std::forward_list is useful. We want to
180 // store each Item in a place where its address won't change. So a node-
181 // based container is appropriate. But we don't need searchability.
183
184 boost::container::flat_map<std::string, Item const*> names_{};
185 boost::container::flat_map<KeyType, Item const*> types_{};
186 friend Derived;
187};
188
189} // 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:96
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:49
T size(T... args)
T substr(T... args)