Skip to content

Commit

Permalink
SW-8706 Add KnowledgeRecord::share_any<T> (#111)
Browse files Browse the repository at this point in the history
* Add share_any<T>() methods

* Add tests for Any methods in KnowledgeBase
  • Loading branch information
dskyle committed Oct 4, 2018
1 parent 35cf30d commit 91a0bfa
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 6 deletions.
12 changes: 10 additions & 2 deletions include/madara/knowledge/DefaultTypeHandlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,16 @@ constexpr auto get_type_handler_save_json(type<T>, overload_priority<12>)
{
knowledge::json_oarchive archive(o);
const char* tag = knowledge::AnyRegistry::get_type_name<T>();
archive.setNextName(tag ? (std::string("Any<") + tag + ">").c_str()
: "Any<UKNOWN_ANY_TYPE>");
std::string name;
if (tag)
{
name = std::string("Any<") + tag + ">";
archive.setNextName(name.c_str());
}
else
{
archive.setNextName("Any<UKNOWN_ANY_TYPE>");
}
archive << val;
}
};
Expand Down
46 changes: 46 additions & 0 deletions include/madara/knowledge/KnowledgeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,52 @@ class MADARA_EXPORT KnowledgeBase
return nullptr;
}

/**
* Gets the contents of a record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T>
std::shared_ptr<const T> share_any(
const VariableReference& key, const KnowledgeReferenceSettings& settings =
KnowledgeReferenceSettings()) const
{
if (impl_)
{
return impl_->share_any<T>(key, settings);
}
else if (context_)
{
return context_->share_any<T>(key, settings);
}

return nullptr;
}

/**
* Gets the contents of a record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T>
std::shared_ptr<const T> share_any(
const std::string& key, const KnowledgeReferenceSettings& settings =
KnowledgeReferenceSettings()) const
{
if (impl_)
{
return impl_->share_any<T>(key, settings);
}
else if (context_)
{
return context_->share_any<T>(key, settings);
}

return nullptr;
}

/**
* Marks the variable reference as updated
* @param variable reference to a variable (@see get_ref)
Expand Down
14 changes: 14 additions & 0 deletions include/madara/knowledge/KnowledgeBaseImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,20 @@ class KnowledgeBaseImpl
return map_.share_any(std::forward<K>(key), settings);
}

/**
* Gets the contents of a record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T, typename K>
std::shared_ptr<const T> share_any(
K&& key, const KnowledgeReferenceSettings& settings =
KnowledgeReferenceSettings()) const
{
return map_.share_any<T>(std::forward<K>(key), settings);
}

/**
* Marks the variable reference as updated
* @param variable reference to a variable (@see get_ref)
Expand Down
9 changes: 9 additions & 0 deletions include/madara/knowledge/KnowledgeRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,15 @@ class MADARA_EXPORT KnowledgeRecord
**/
std::shared_ptr<const ConstAny> share_any() const;

/**
* Gets the contents of this record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T>
std::shared_ptr<const T> share_any() const;

/**
* Creates a deep copy of the knowledge record. Because each
* Knowledge Record may contain non-thread-safe ref counted values,
Expand Down
13 changes: 13 additions & 0 deletions include/madara/knowledge/KnowledgeRecord.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,19 @@ inline std::shared_ptr<const ConstAny> KnowledgeRecord::share_any() const
return nullptr;
}

template<typename T>
inline std::shared_ptr<const T> KnowledgeRecord::share_any() const
{
auto any_ptr = share_any();
if (!any_ptr)
{
throw exceptions::BadAnyAccess("KnowledgeRecord::share_any<T>: "
"value in record is not an Any");
}
const T &ref = any_ptr->template ref<T>();
return {any_ptr, &ref};
}

inline std::shared_ptr<KnowledgeRecord::CircBuf>
KnowledgeRecord::share_circular_buffer() const
{
Expand Down
30 changes: 30 additions & 0 deletions include/madara/knowledge/ThreadSafeContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,36 @@ class MADARA_EXPORT ThreadSafeContext
key, settings);
}

/**
* Gets the contents of a record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T>
std::shared_ptr<const T> share_any(
const std::string& key, const KnowledgeReferenceSettings& settings =
KnowledgeReferenceSettings()) const
{
return get_shared<const T, &KnowledgeRecord::share_any>(
key, settings);
}

/**
* Gets the contents of a record as a shared pointer to the given type.
* @tparam T type requested
* @return a shared_ptr, sharing with the internal one.
* @throw BadAnyAccess if this record is not an Any holding the given type
**/
template<typename T>
std::shared_ptr<const T> share_any(
const VariableReference& key, const KnowledgeReferenceSettings& settings =
KnowledgeReferenceSettings()) const
{
return get_shared<const T, &KnowledgeRecord::share_any>(
key, settings);
}

/**
* Atomically returns a reference to the variable. Variable references are
* efficient mechanisms for reference variables individually--similar to
Expand Down
28 changes: 24 additions & 4 deletions tests/test_any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ void test_record()
}
}

template<typename T>
void test_map(T& kb)
void test_kb(KnowledgeBase& kb)
{
kb.set("hello_str", "world");
kb.set_any("hello", std::string("world"));
Expand All @@ -288,6 +287,27 @@ void test_map(T& kb)
auto a0 = kb.share_any("asdf");
TEST_EQ(a0->template ref<std::vector<std::string>>()[2], "c");

auto sv0 = kb.template share_any<std::vector<std::string>>("asdf");
TEST_EQ(sv0->at(1), "b");
}

void test_map(ThreadSafeContext& kb)
{
kb.set("hello_str", "world");
kb.set_any("hello", std::string("world"));
TEST_EQ(kb.get("hello").template get_any_cref<std::string>(), "world");

kb.emplace_any(
"asdf", type<std::vector<std::string>>{}, mk_init({"a", "b", "c"}));
TEST_EQ(
kb.get("asdf").template get_any_cref<std::vector<std::string>>()[1], "b");

auto a0 = kb.share_any("asdf");
TEST_EQ(a0->template ref<std::vector<std::string>>()[2], "c");

auto sv0 = kb.template share_any<std::vector<std::string>>("asdf");
TEST_EQ(sv0->at(1), "b");

kb.set_any("B", ns::B{3, 3.5, 4.25});

std::string kb_dump;
Expand Down Expand Up @@ -777,8 +797,8 @@ int main(int, char**)
test_map(kb.get_context());
}
{
// KnowledgeBase kb;
// test_map(kb);
KnowledgeBase kb;
test_kb(kb);
}

test_geo();
Expand Down

0 comments on commit 91a0bfa

Please sign in to comment.