///|/ Copyright (c) Prusa Research 2023 Tomáš Mészáros @tamasmeszaros ///|/ ///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher ///|/ #ifndef ARBITRARYDATASTORE_HPP #define ARBITRARYDATASTORE_HPP #include #include #include #include namespace Slic3r { namespace arr2 { // An associative container able to store and retrieve any data type. // Based on std::any class ArbitraryDataStore { std::map m_data; public: template void add(const std::string &key, T &&data) { m_data[key] = std::any{std::forward(data)}; } void add(const std::string &key, std::any &&data) { m_data[key] = std::move(data); } // Return nullptr if the key does not exist or the stored data has a // type other then T. Otherwise returns a pointer to the stored data. template const T *get(const std::string &key) const { auto it = m_data.find(key); return it != m_data.end() ? std::any_cast(&(it->second)) : nullptr; } // Same as above just not const. template T *get(const std::string &key) { auto it = m_data.find(key); return it != m_data.end() ? std::any_cast(&(it->second)) : nullptr; } bool has_key(const std::string &key) const { auto it = m_data.find(key); return it != m_data.end(); } }; // Some items can be containers of arbitrary data stored under string keys. template<> struct DataStoreTraits_ { static constexpr bool Implemented = true; template static const T *get(const ArbitraryDataStore &s, const std::string &key) { return s.get(key); } // Same as above just not const. template static T *get(ArbitraryDataStore &s, const std::string &key) { return s.get(key); } template static bool has_key(ArbitraryDataStore &s, const std::string &key) { return s.has_key(key); } }; template<> struct WritableDataStoreTraits_ { static constexpr bool Implemented = true; template static void set(ArbitraryDataStore &store, const std::string &key, T &&data) { store.add(key, std::forward(data)); } }; }} // namespace Slic3r::arr2 #endif // ARBITRARYDATASTORE_HPP