123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #ifndef CNSTREAM_COLLECTION_HPP_
- #define CNSTREAM_COLLECTION_HPP_
- #include <memory>
- #include <mutex>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include "cnstream_common.hpp"
- #include "cnstream_logging.hpp"
- #include "util/cnstream_any.hpp"
- namespace cnstream {
- class Collection : public NonCopyable {
- public:
-
- Collection() = default;
-
- ~Collection() = default;
-
- template <typename ValueT>
- ValueT& Get(const std::string& tag);
-
- template <typename ValueT>
- ValueT& Add(const std::string& tag, const ValueT& value);
-
- template <typename ValueT>
- ValueT& Add(const std::string& tag, ValueT&& value);
-
- template <typename ValueT>
- bool AddIfNotExists(const std::string& tag, const ValueT& value);
-
- template <typename ValueT>
- bool AddIfNotExists(const std::string& tag, ValueT&& value);
-
- bool HasValue(const std::string& tag);
- #if !defined(_LIBCPP_NO_RTTI)
-
- const std::type_info& Type(const std::string& tag);
-
- template <typename ValueT>
- bool TaggedIsOfType(const std::string& tag);
- #endif
- private:
- void Add(const std::string& tag, std::unique_ptr<cnstream::any>&& value);
- bool AddIfNotExists(const std::string& tag, std::unique_ptr<cnstream::any>&& value);
- private:
- std::unordered_map<std::string, std::unique_ptr<cnstream::any>> data_;
- std::mutex data_mtx_;
- };
- template <typename ValueT>
- ValueT& Collection::Get(const std::string& tag) {
- std::lock_guard<std::mutex> lk(data_mtx_);
- auto iter = data_.find(tag);
- if (data_.end() == iter) {
- LOGF(COLLECTION) << "No data tagged by [" << tag << "] has been added.";
- }
- try {
- return any_cast<ValueT&>(*iter->second);
- } catch (bad_any_cast& e) {
- #if !defined(_LIBCPP_NO_RTTI)
- LOGF(COLLECTION) << "The type of data tagged by [" << tag << "] is ["
- << iter->second->type().name()
- << "]. Expect type is [" << typeid(ValueT).name() << "].";
- #else
- LOGF(COLLECTION) << "The type of data tagged by [" << tag << "] is not the "
- "expected data type."
- #endif
- }
-
- return any_cast<ValueT&>(*iter->second);
- }
- template <typename ValueT> inline
- ValueT& Collection::Add(const std::string& tag, const ValueT& value) {
- Add(tag, std::unique_ptr<cnstream::any>(new cnstream::any(value)));
- return Get<ValueT>(tag);
- }
- template <typename ValueT> inline
- ValueT& Collection::Add(const std::string& tag, ValueT&& value) {
- Add(tag, std::unique_ptr<cnstream::any>(new cnstream::any(std::forward<ValueT>(value))));
- return Get<ValueT>(tag);
- }
- template <typename ValueT> inline
- bool Collection::AddIfNotExists(const std::string& tag, const ValueT& value) {
- return AddIfNotExists(tag, std::unique_ptr<cnstream::any>(new cnstream::any(value)));
- }
- template <typename ValueT> inline
- bool Collection::AddIfNotExists(const std::string& tag, ValueT&& value) {
- return AddIfNotExists(tag, std::unique_ptr<cnstream::any>(new cnstream::any(std::forward<ValueT>(value))));
- }
- #if !defined(_LIBCPP_NO_RTTI)
- template <typename ValueT> inline
- bool Collection::TaggedIsOfType(const std::string& tag) {
- if (!HasValue(tag)) return false;
- return typeid(ValueT) == Type(tag);
- }
- #endif
- }
- #endif
|