feat(reflect-cpp): Switched from glaze -> reflect cpp
A bug was discovered in glaze which prevented valid toml output. We have switched to toml++ and reflect-cpp. The interface has remained the same so this should not break any code
This commit is contained in:
248
build-config/reflect-cpp/include/rfl/Object.hpp
Normal file
248
build-config/reflect-cpp/include/rfl/Object.hpp
Normal file
@@ -0,0 +1,248 @@
|
||||
#ifndef RFL_OBJECT_HPP_
|
||||
#define RFL_OBJECT_HPP_
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Result.hpp"
|
||||
|
||||
namespace rfl {
|
||||
|
||||
/// Used to embed additional fields for which the names cannot be known in
|
||||
/// advance and can therefore not be encoded in the struct.
|
||||
template <class T>
|
||||
class Object {
|
||||
public:
|
||||
using DataType = std::vector<std::pair<std::string, T>>;
|
||||
using Type = T;
|
||||
|
||||
/// We want this to behave as similarly to C++ standard containers as
|
||||
/// possible.
|
||||
using key_type = std::string;
|
||||
using mapped_type = T;
|
||||
using value_type = std::pair<std::string, T>;
|
||||
using size_type = typename DataType::size_type;
|
||||
using difference_type = typename DataType::size_type;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = typename DataType::pointer;
|
||||
using const_pointer = typename DataType::const_pointer;
|
||||
using iterator = typename DataType::iterator;
|
||||
using const_iterator = typename DataType::const_iterator;
|
||||
using reverse_iterator = typename DataType::reverse_iterator;
|
||||
using const_reverse_iterator = typename DataType::const_reverse_iterator;
|
||||
|
||||
Object() : data_(), i_(0) {}
|
||||
|
||||
Object(const Object<T>& _f) = default;
|
||||
|
||||
Object(Object<T>&& _f) noexcept = default;
|
||||
|
||||
~Object() = default;
|
||||
|
||||
/// Iterator to the beginning.
|
||||
auto begin() { return data_.begin(); }
|
||||
|
||||
/// Iterator to the beginning.
|
||||
auto begin() const { return data_.begin(); }
|
||||
|
||||
/// Const iterator to the beginning.
|
||||
auto cbegin() const { return data_.cbegin(); }
|
||||
|
||||
/// Iterator to the end.
|
||||
auto end() { return data_.end(); }
|
||||
|
||||
/// Iterator to the end.
|
||||
auto end() const { return data_.end(); }
|
||||
|
||||
/// Const iterator to the end.
|
||||
auto cend() const { return data_.cend(); }
|
||||
|
||||
/// Reverse iterator.
|
||||
auto rbegin() { return data_.rbegin(); }
|
||||
|
||||
/// Reverse iterator.
|
||||
auto rbegin() const { return data_.rbegin(); }
|
||||
|
||||
/// Const reverse iterator.
|
||||
auto crbegin() const { return data_.crbegin(); }
|
||||
|
||||
/// Reverse iterator.
|
||||
auto rend() { return data_.rend(); }
|
||||
|
||||
/// Reverse iterator.
|
||||
auto rend() const { return data_.rend(); }
|
||||
|
||||
/// Const reverse iterator.
|
||||
auto crend() const { return data_.crend(); }
|
||||
|
||||
Object<T>& operator=(const Object<T>& _f) = default;
|
||||
|
||||
Object<T>& operator=(Object<T>&& _f) = default;
|
||||
|
||||
/// Whether the object is empty.
|
||||
auto empty() const { return data_.size() == 0; }
|
||||
|
||||
/// The number of elements currently inside the object.
|
||||
auto size() const { return data_.size(); }
|
||||
|
||||
std::size_t count(const key_type& key) const { return std::count_if(cbegin(), cend(), [&](const auto& p) { return p.first == key; }); }
|
||||
|
||||
/// The maximum possible size.
|
||||
auto max_size() const { return data_.max_size(); }
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
template <class... Args>
|
||||
void insert(const Args&... _values) {
|
||||
(data_.push_back(_values), ...);
|
||||
i_ = 0;
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
template <class... Args>
|
||||
void insert(Args&&... _values) {
|
||||
(data_.emplace_back(std::move(_values)), ...);
|
||||
i_ = 0;
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
void insert(const std::string& _k, const T& _v) {
|
||||
insert(std::make_pair(_k, _v));
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
void insert(const std::string& _k, T&& _v) {
|
||||
insert(std::make_pair(_k, std::move(_v)));
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
void insert(std::string&& _k, T&& _v) {
|
||||
insert(std::make_pair(std::move(_k), std::move(_v)));
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
void insert(const std::string_view& _k, const T& _v) {
|
||||
insert(std::make_pair(std::string(_k), _v));
|
||||
}
|
||||
|
||||
/// Inserts a new element at the end.
|
||||
void insert(const std::string_view& _k, T&& _v) {
|
||||
insert(std::make_pair(std::string(_k), std::move(_v)));
|
||||
}
|
||||
|
||||
/// Alias for insert that primarily exists for compatability with standard
|
||||
/// containers.
|
||||
template <class... Args>
|
||||
void emplace(Args&&... _args) {
|
||||
insert(std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
/// Alias for insert that primarily exists for compatability with standard
|
||||
/// containers.
|
||||
template <class... Args>
|
||||
void emplace(const Args&... _args) {
|
||||
insert(_args...);
|
||||
}
|
||||
|
||||
/// Inserts several new elements at the end.
|
||||
template <class InputIt>
|
||||
void insert_range(InputIt _first, InputIt _last) {
|
||||
for (auto it = _first; it != _last; ++it) {
|
||||
insert(*it);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts several new elements at the end.
|
||||
template <class RangeType>
|
||||
void insert_range(RangeType _range) {
|
||||
for (const auto& val : _range) {
|
||||
insert(val);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the element signified by the key or creates a new one.
|
||||
T& operator[](const std::string& _key) {
|
||||
const auto i = find(_key);
|
||||
if (i != size()) {
|
||||
return data_[i].second;
|
||||
}
|
||||
data_.emplace_back(std::make_pair(_key, T()));
|
||||
i_ = 0;
|
||||
return data_.back().second;
|
||||
}
|
||||
|
||||
/// Returns the element signified by the key or creates a new one.
|
||||
T& operator[](std::string&& _key) {
|
||||
const auto i = find(_key);
|
||||
if (i != size()) {
|
||||
return data_[i].second;
|
||||
}
|
||||
data_.emplace_back(std::make_pair(std::move(_key), T()));
|
||||
i_ = 0;
|
||||
return data_.back().second;
|
||||
}
|
||||
|
||||
/// Deletes all elements.
|
||||
void clear() {
|
||||
data_.clear();
|
||||
i_ = 0;
|
||||
}
|
||||
|
||||
/// Returns the element signified by the key or throws an exception.
|
||||
T& at(const std::string& _key) {
|
||||
const auto i = find(_key);
|
||||
if (i == size()) {
|
||||
throw std::runtime_error("Key named '" + _key + "' not found.");
|
||||
}
|
||||
return data_[i].second;
|
||||
}
|
||||
|
||||
/// Returns the element signified by the key or throws an exception.
|
||||
const T& at(const std::string& _key) const {
|
||||
const auto i = find(_key);
|
||||
if (i == size()) {
|
||||
throw std::runtime_error("Key named '" + _key + "' not found.");
|
||||
}
|
||||
return data_[i].second;
|
||||
}
|
||||
|
||||
/// Returns a result wrapping the element signified by the key.
|
||||
Result<T> get(const std::string& _key) const noexcept {
|
||||
const auto i = find(_key);
|
||||
if (i == size()) {
|
||||
return error("Key named '" + _key + "' not found.");
|
||||
}
|
||||
return data_[i].second;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t find(const std::string& _key) const {
|
||||
for (size_t i = i_; i < size(); ++i) {
|
||||
if (data_[i].first == _key) {
|
||||
i_ = i + 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < i_; ++i) {
|
||||
if (data_[i].first == _key) {
|
||||
i_ = i + 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return size();
|
||||
}
|
||||
|
||||
private:
|
||||
DataType data_;
|
||||
|
||||
/// Allows faster access
|
||||
mutable size_t i_;
|
||||
};
|
||||
|
||||
} // namespace rfl
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user