diff options
Diffstat (limited to 'src/ipa/raspberrypi/controller/metadata.hpp')
-rw-r--r-- | src/ipa/raspberrypi/controller/metadata.hpp | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/src/ipa/raspberrypi/controller/metadata.hpp b/src/ipa/raspberrypi/controller/metadata.hpp index f3a8dfab..fd6aac88 100644 --- a/src/ipa/raspberrypi/controller/metadata.hpp +++ b/src/ipa/raspberrypi/controller/metadata.hpp @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (C) 2019, Raspberry Pi (Trading) Limited + * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited * * metadata.hpp - general metadata class */ @@ -8,68 +8,104 @@ // A simple class for carrying arbitrary metadata, for example about an image. -#include <string> -#include <mutex> +#include <any> #include <map> #include <memory> - -#include <boost/any.hpp> +#include <mutex> +#include <string> namespace RPiController { class Metadata { public: - template<typename T> void Set(std::string const &tag, T const &value) + Metadata() = default; + + Metadata(Metadata const &other) { - std::lock_guard<std::mutex> lock(mutex_); + std::scoped_lock other_lock(other.mutex_); + data_ = other.data_; + } + + Metadata(Metadata &&other) + { + std::scoped_lock other_lock(other.mutex_); + data_ = std::move(other.data_); + other.data_.clear(); + } + + template<typename T> + void Set(std::string const &tag, T const &value) + { + std::scoped_lock lock(mutex_); data_[tag] = value; } - template<typename T> int Get(std::string const &tag, T &value) const + + template<typename T> + int Get(std::string const &tag, T &value) const { - std::lock_guard<std::mutex> lock(mutex_); + std::scoped_lock lock(mutex_); auto it = data_.find(tag); if (it == data_.end()) return -1; - value = boost::any_cast<T>(it->second); + value = std::any_cast<T>(it->second); return 0; } + void Clear() { - std::lock_guard<std::mutex> lock(mutex_); + std::scoped_lock lock(mutex_); data_.clear(); } + Metadata &operator=(Metadata const &other) { - std::lock_guard<std::mutex> lock(mutex_); - std::lock_guard<std::mutex> other_lock(other.mutex_); + std::scoped_lock lock(mutex_, other.mutex_); data_ = other.data_; return *this; } - template<typename T> T *GetLocked(std::string const &tag) + + Metadata &operator=(Metadata &&other) + { + std::scoped_lock lock(mutex_, other.mutex_); + data_ = std::move(other.data_); + other.data_.clear(); + return *this; + } + + void Merge(Metadata &other) + { + std::scoped_lock lock(mutex_, other.mutex_); + data_.merge(other.data_); + } + + template<typename T> + T *GetLocked(std::string const &tag) { // This allows in-place access to the Metadata contents, // for which you should be holding the lock. auto it = data_.find(tag); if (it == data_.end()) return nullptr; - return boost::any_cast<T>(&it->second); + return std::any_cast<T>(&it->second); } + template<typename T> void SetLocked(std::string const &tag, T const &value) { // Use this only if you're holding the lock yourself. data_[tag] = value; } + // Note: use of (lowercase) lock and unlock means you can create scoped // locks with the standard lock classes. - // e.g. std::lock_guard<PisP::Metadata> lock(metadata) + // e.g. std::lock_guard<RPiController::Metadata> lock(metadata) void lock() { mutex_.lock(); } void unlock() { mutex_.unlock(); } private: mutable std::mutex mutex_; - std::map<std::string, boost::any> data_; + std::map<std::string, std::any> data_; }; typedef std::shared_ptr<Metadata> MetadataPtr; |