};
/**
+ * @brief enum property
+ *
+ * @tparam T underlying type info to query enum_info
+ */
+template <typename EnumInfo>
+class EnumProperty : public Property<typename EnumInfo::Enum> {
+public:
+ static EnumInfo enum_info_;
+};
+
+/**
* @brief abstract class for positive integer
*
*/
};
/**
+ * @brief str converter specialization for enum classes
+ *
+ * @tparam EnumInfo enum informations
+ */
+template <typename EnumInfo>
+struct str_converter<enum_class_prop_tag, EnumInfo> {
+
+ /**
+ * @copydoc template <typename Tag, typename DataType> struct str_converter
+ */
+ static std::string to_string(const typename EnumInfo::Enum &value) {
+ constexpr auto size = EnumInfo::EnumList.size();
+ constexpr const auto data = std::data(EnumInfo::EnumList);
+ for (unsigned i = 0; i < size; ++i) {
+ if (data[i] == value) {
+ return EnumInfo::EnumStr[i];
+ }
+ }
+ throw std::invalid_argument("Cannot find value in the enum list");
+ }
+
+ /**
+ * @copydoc template <typename Tag, typename DataType> struct str_converter
+ */
+ static typename EnumInfo::Enum from_string(const std::string &value) {
+ constexpr auto size = EnumInfo::EnumList.size();
+ constexpr const auto data = std::data(EnumInfo::EnumList);
+ for (unsigned i = 0; i < size; ++i) {
+ if (istrequal(EnumInfo::EnumStr[i], value.c_str())) {
+ return data[i];
+ }
+ }
+ throw std::invalid_argument("No matching enum for value: " + value);
+ }
+};
+
+/**
* @brief str converter which serializes a pointer and returns back to a ptr
*
* @tparam DataType pointer type
using info = prop_info<T>;
using tag_type =
typename tag_cast<typename info::tag_type, int_prop_tag, uint_prop_tag,
- dimension_prop_tag, float_prop_tag, str_prop_tag>::type;
+ dimension_prop_tag, float_prop_tag, str_prop_tag,
+ enum_class_prop_tag>::type;
using data_type = typename info::data_type;
- return str_converter<tag_type, data_type>::to_string(property.get());
+ if constexpr (std::is_same_v<tag_type, enum_class_prop_tag>) {
+ return str_converter<tag_type, decltype(T::enum_info_)>::to_string(
+ property.get());
+ } else {
+ return str_converter<tag_type, data_type>::to_string(property.get());
+ }
}
/**
using info = prop_info<T>;
using tag_type =
typename tag_cast<typename info::tag_type, int_prop_tag, uint_prop_tag,
- dimension_prop_tag, float_prop_tag, str_prop_tag>::type;
+ dimension_prop_tag, float_prop_tag, str_prop_tag,
+ enum_class_prop_tag>::type;
using data_type = typename info::data_type;
- property.set(str_converter<tag_type, data_type>::from_string(str));
+ if constexpr (std::is_same_v<tag_type, enum_class_prop_tag>) {
+ property.set(
+ str_converter<tag_type, decltype(T::enum_info_)>::from_string(str));
+ } else {
+ property.set(str_converter<tag_type, data_type>::from_string(str));
+ }
}
/**
static constexpr const char *key = "ptr_banana";
using prop_tag = nntrainer::ptr_prop_tag;
};
+
+/**
+ * @brief Enuminformation of BananaType;
+ *
+ */
+struct BananaEnumInfo {
+ /**
+ * @brief underlying enum
+ *
+ */
+ enum class Enum {
+ Cavendish = 0,
+ Plantain = 1,
+ Manzano = 2,
+ };
+
+ static constexpr std::initializer_list<Enum> EnumList = {
+ Enum::Cavendish, Enum::Plantain, Enum::Manzano};
+
+ static constexpr const char *EnumStr[] = {"Cavendish", "Plantain", "Manzano"};
+};
+
+/**
+ * @brief Type of Banana (enum based)
+ *
+ */
+class BananaType : public nntrainer::EnumProperty<BananaEnumInfo> {
+public:
+ using prop_tag = nntrainer::enum_class_prop_tag;
+ static constexpr const char *key = "banana_type";
+};
+
} // namespace
TEST(BasicProperty, tagCast) {
EXPECT_FLOAT_EQ(q.get(), 1.3245f);
}
+ { /**< enum type test from_string -> get */
+ BananaType t;
+ nntrainer::from_string("CAVENDISH", t);
+ EXPECT_EQ(t.get(), BananaEnumInfo::Enum::Cavendish);
+ nntrainer::from_string("Plantain", t);
+ EXPECT_EQ(t.get(), BananaEnumInfo::Enum::Plantain);
+ nntrainer::from_string("manzano", t);
+ EXPECT_EQ(t.get(), BananaEnumInfo::Enum::Manzano);
+ }
+
+ { /**< enum type test set -> to_string */
+ BananaType t;
+ t.set(BananaEnumInfo::Enum::Cavendish);
+ EXPECT_EQ("Cavendish", nntrainer::to_string(t));
+ t.set(BananaEnumInfo::Enum::Plantain);
+ EXPECT_EQ("Plantain", nntrainer::to_string(t));
+ t.set(BananaEnumInfo::Enum::Manzano);
+ EXPECT_EQ("Manzano", nntrainer::to_string(t));
+ }
+
{ /**< from_string -> get / to_string, uint vector prop */
std::vector<NumBanana> bananas;
EXPECT_EQ(nntrainer::getPropKey(bananas), "num_banana");