Skip to content

Commit

Permalink
Add integral any poly types
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Armstrong committed Jul 22, 2024
1 parent 03098fc commit f1f4754
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 2 deletions.
19 changes: 19 additions & 0 deletions tesseract_common/include/tesseract_common/any_poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ TESSERACT_COMMON_IGNORE_WARNINGS_POP
#include <tesseract_common/serialization.h>
#include <tesseract_common/type_erasure.h>

#include <string>
#include <unordered_map>

#define COMMA ,

/** @brief If shared library, this must go in the header after the class definition */
#define TESSERACT_ANY_EXPORT_KEY(C, K) \
namespace tesseract_serialization::any_poly \
Expand Down Expand Up @@ -78,6 +83,7 @@ struct AnyConcept // NOLINT
A assign = c;
bool eq = (c == cp);
bool neq = (c != cp);
UNUSED(assign);
UNUSED(eq);
UNUSED(neq);
}
Expand Down Expand Up @@ -131,4 +137,17 @@ BOOST_CLASS_TRACKING(tesseract_common::AnyPolyBase, boost::serialization::track_
BOOST_CLASS_EXPORT_KEY(tesseract_common::AnyPoly)
BOOST_CLASS_TRACKING(tesseract_common::AnyPoly, boost::serialization::track_never)

TESSERACT_ANY_EXPORT_KEY(bool, IntegralBool)
TESSERACT_ANY_EXPORT_KEY(int, IntegralInt)
TESSERACT_ANY_EXPORT_KEY(unsigned, IntegralUnsigned)
TESSERACT_ANY_EXPORT_KEY(double, IntegralDouble)
TESSERACT_ANY_EXPORT_KEY(float, IntegralFloat)
TESSERACT_ANY_EXPORT_KEY(std::string, StdString)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA std::string>, StdUnorderedMapStringString)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA bool>, StdUnorderedMapStringBool)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA int>, StdUnorderedMapStringInt)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA unsigned>, StdUnorderedMapStringUnsigned)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA double>, StdUnorderedMapStringDouble)
TESSERACT_ANY_EXPORT_KEY(std::unordered_map<std::string COMMA float>, StdUnorderedMapStringFloat)

#endif // TESSERACT_COMMON_ANY_POLY_H
2 changes: 1 addition & 1 deletion tesseract_common/include/tesseract_common/type_erasure.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct TypeErasureInstance : ConceptInterface
using ConceptValueType = ConcreteType;
using ConceptInterfaceType = ConceptInterface;

TypeErasureInstance() = default;
TypeErasureInstance() = default; // NOLINT(cppcoreguidelines-pro-type-member-init)

explicit TypeErasureInstance(ConcreteType value) : value_(std::move(value)) {}

Expand Down
2 changes: 1 addition & 1 deletion tesseract_common/include/tesseract_common/yaml_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ inline void checkForUnknownKeys(const YAML::Node& node, const std::set<std::stri

for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
{
std::string key = it->first.as<std::string>();
auto key = it->first.as<std::string>();
if (expected_keys.find(key) == expected_keys.end())
throw std::runtime_error("checkForUnknownKeys, unknown key: " + key);
}
Expand Down
16 changes: 16 additions & 0 deletions tesseract_common/src/any_poly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#include <tesseract_common/any_poly.h>

#include <boost/serialization/unordered_map.hpp>

namespace tesseract_common
{
template <class Archive>
Expand All @@ -42,3 +44,17 @@ TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_common::AnyPoly)

BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_common::AnyPolyBase)
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_common::AnyPoly)

TESSERACT_ANY_EXPORT_IMPLEMENT(IntegralBool)
TESSERACT_ANY_EXPORT_IMPLEMENT(IntegralInt)
TESSERACT_ANY_EXPORT_IMPLEMENT(IntegralUnsigned)
TESSERACT_ANY_EXPORT_IMPLEMENT(IntegralDouble)
TESSERACT_ANY_EXPORT_IMPLEMENT(IntegralFloat)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdString)

TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringString)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringBool)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringInt)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringUnsigned)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringDouble)
TESSERACT_ANY_EXPORT_IMPLEMENT(StdUnorderedMapStringFloat)
98 changes: 98 additions & 0 deletions tesseract_common/test/tesseract_common_unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,104 @@ TEST(TesseractCommonUnit, anyUnit) // NOLINT
EXPECT_ANY_THROW(nany_type.as<tesseract_common::Toolpath>()); // NOLINT
}

template <typename T>
void runAnyPolyIntegralTest(T value, const std::string& type_str)
{
tesseract_common::AnyPoly any_type{ value };
EXPECT_TRUE(any_type.getType() == std::type_index(typeid(T)));
EXPECT_TRUE(any_type.as<T>() == value);

// Check clone
tesseract_common::AnyPoly any_copy = any_type;
EXPECT_TRUE(any_copy == any_type);
EXPECT_TRUE(any_copy.as<T>() == value);

const std::string filepath{ tesseract_common::getTempPath() + "any_" + type_str + "_type_boost.xml" };
{
std::ofstream os(filepath);
boost::archive::xml_oarchive oa(os);
oa << BOOST_SERIALIZATION_NVP(any_type);
}

tesseract_common::AnyPoly nany_type;
{
std::ifstream ifs(filepath);
assert(ifs.good());
boost::archive::xml_iarchive ia(ifs);

// restore the schedule from the archive
ia >> BOOST_SERIALIZATION_NVP(nany_type);
}

EXPECT_TRUE(nany_type.getType() == std::type_index(typeid(T)));
EXPECT_TRUE(nany_type.as<T>() == value);

// Test bad cast
EXPECT_ANY_THROW(nany_type.as<tesseract_common::Toolpath>()); // NOLINT
}

TEST(TesseractCommonUnit, anyIntegralTypesUnit) // NOLINT
{
runAnyPolyIntegralTest<bool>(true, "bool");
runAnyPolyIntegralTest<int>(-10, "int");
runAnyPolyIntegralTest<unsigned>(5, "unsigned");
runAnyPolyIntegralTest<double>(1.2, "double");
runAnyPolyIntegralTest<float>(-0.2F, "float");
runAnyPolyIntegralTest<std::string>("this", "string");
}

template <typename T>
void runAnyPolyUnorderedMapIntegralTest(T value, const std::string& type_str)
{
std::unordered_map<std::string, T> data;
data["test"] = value;
tesseract_common::AnyPoly any_type{ data };
EXPECT_TRUE(any_type.getType() == std::type_index(typeid(std::unordered_map<std::string, T>)));
bool check = any_type.as<std::unordered_map<std::string, T>>() == data;
EXPECT_TRUE(check);

// Check clone
tesseract_common::AnyPoly any_copy = any_type;
EXPECT_TRUE(any_copy == any_type);
check = any_copy.as<std::unordered_map<std::string, T>>() == data;
EXPECT_TRUE(check);

const std::string filepath{ tesseract_common::getTempPath() + "any_unordered_map_string_" + type_str +
"_type_boost.xml" };
{
std::ofstream os(filepath);
boost::archive::xml_oarchive oa(os);
oa << BOOST_SERIALIZATION_NVP(any_type);
}

tesseract_common::AnyPoly nany_type;
{
std::ifstream ifs(filepath);
assert(ifs.good());
boost::archive::xml_iarchive ia(ifs);

// restore the schedule from the archive
ia >> BOOST_SERIALIZATION_NVP(nany_type);
}

EXPECT_TRUE(nany_type.getType() == std::type_index(typeid(std::unordered_map<std::string, T>)));
check = nany_type.as<std::unordered_map<std::string COMMA T>>() == data;
EXPECT_TRUE(check);

// Test bad cast
EXPECT_ANY_THROW(nany_type.as<tesseract_common::Toolpath>()); // NOLINT
}

TEST(TesseractCommonUnit, anyUnorderedMapIntegralTypesUnit) // NOLINT
{
runAnyPolyUnorderedMapIntegralTest<bool>(true, "bool");
runAnyPolyUnorderedMapIntegralTest<int>(-10, "int");
runAnyPolyUnorderedMapIntegralTest<unsigned>(5, "unsigned");
runAnyPolyUnorderedMapIntegralTest<double>(1.2, "double");
runAnyPolyUnorderedMapIntegralTest<float>(-0.2F, "float");
runAnyPolyUnorderedMapIntegralTest<std::string>("this", "string");
}

TEST(TesseractCommonUnit, anySharedPtrUnit) // NOLINT
{
tesseract_common::AnyPoly any_type;
Expand Down

0 comments on commit f1f4754

Please sign in to comment.