Browse Source

Added associative container constructor to `object`

Added `is_associative_container`, `is_map`, `is_unordered_map`
TODO: add tests
master
Jessica James 5 years ago
parent
commit
120feb508e
  1. 8
      src/common/app_parameters.cpp
  2. 32
      src/include/object.hpp
  3. 60
      src/include/type_traits.hpp

8
src/common/app_parameters.cpp

@ -122,17 +122,11 @@ object app_parameters::as_object() const {
return object{};
}
// Transform m_values into appropriate map type; TODO: add helper to object for this
std::map<std::string, object> values_map;
for (auto& value : m_values) {
values_map.emplace(value.first, value.second);
}
return std::map<std::string, object>{
{ "Path", m_path },
{ "Args", m_args },
{ "Switches", m_switches },
{ "Values", values_map }
{ "Values", m_values }
};
}

32
src/include/object.hpp

@ -71,8 +71,9 @@ public:
};
template<typename T>
struct is_backing<T, typename std::enable_if<std::is_same<T, map_t>::value>::type> {
static constexpr bool value = true;
struct is_backing<T, typename std::enable_if<is_associative_container<T>::value>::type> {
static constexpr bool value = std::is_same<typename is_associative_container<T>::key_type, std::string>::value
&& std::is_same<typename is_associative_container<T>::value_type, object>::value;
using type = map_t;
};
@ -97,7 +98,8 @@ public:
// Value constructors
template<typename T,
typename std::enable_if<is_backing<typename std::decay<T>::type>::value
&& !is_sequence_container<typename std::decay<T>::type>::value>::type* = nullptr>
&& !is_sequence_container<typename std::decay<T>::type>::value
&& (!is_associative_container<typename std::decay<T>::type>::value || std::is_same<typename remove_cvref<T>::type, map_t>::value)>::type* = nullptr>
object(T&& in_value)
: m_value{ typename is_backing<typename std::decay<T>::type>::type{ std::forward<T>(in_value) } } {
// Empty ctor body
@ -124,6 +126,30 @@ public:
}
}
// std::unordered_map<std::string, object>
template<typename T,
typename std::enable_if<is_unordered_map<typename std::decay<T>::type>::value
&& std::is_same<typename is_unordered_map<typename std::decay<T>::type>::key_type, std::string>::value
&& std::is_same<typename is_unordered_map<typename std::decay<T>::type>::value_type, object>::value>::type* = nullptr>
object(T&& in_value)
: m_value{ map_t{ in_value.begin(), in_value.end() } } {
// Empty ctor body
}
// Non-map_t associative containers (container<std::string, T>)
template<typename T,
typename std::enable_if<is_associative_container<typename remove_cvref<T>::type>::value
&& (std::is_convertible<typename is_associative_container<typename remove_cvref<T>::type>::key_type, std::string>::value
|| std::is_convertible<typename is_associative_container<typename remove_cvref<T>::type>::key_type, std::string_view>::value)
&& !std::is_same<typename is_associative_container<typename remove_cvref<T>::type>::value_type, object>::value>::type* = nullptr>
object(T&& in_value)
: m_value{ map_t{} } {
auto& map = std::get<map_t>(m_value);
for (auto& pair : in_value) {
map.emplace(pair.first, pair.second);
}
}
object(const char* in_str);
object(const std::string_view& in_str);

60
src/include/type_traits.hpp

@ -30,6 +30,13 @@
namespace jessilib {
/** remove_cvref (can be replaced with C++20) */
template<class T>
struct remove_cvref {
typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};
/** is_vector */
template<typename T>
@ -108,7 +115,7 @@ struct is_unordered_set<std::unordered_set<T>> {
constexpr bool operator()() const noexcept { return true; }
};
/** is_unordered_set */
/** is_unordered_multiset */
template<typename T>
struct is_unordered_multiset : std::false_type {};
@ -121,6 +128,57 @@ struct is_unordered_multiset<std::unordered_multiset<T>> {
constexpr bool operator()() const noexcept { return true; }
};
/** is_map */
template<typename T>
struct is_map : std::false_type {};
template<typename KeyT, typename ValueT>
struct is_map<std::map<KeyT, ValueT>> {
using key_type = KeyT;
using value_type = ValueT;
static constexpr bool value{ true };
constexpr operator bool() const noexcept { return true; }
constexpr bool operator()() const noexcept { return true; }
};
/** is_unordered_map */
template<typename T>
struct is_unordered_map : std::false_type {};
template<typename KeyT, typename ValueT>
struct is_unordered_map<std::unordered_map<KeyT, ValueT>> {
using key_type = KeyT;
using value_type = ValueT;
static constexpr bool value{ true };
constexpr operator bool() const noexcept { return true; }
constexpr bool operator()() const noexcept { return true; }
};
/** is_associative_container */
template<typename T>
struct is_associative_container : std::false_type {};
template<typename KeyT, typename ValueT>
struct is_associative_container<std::map<KeyT, ValueT>> {
using key_type = KeyT;
using value_type = ValueT;
static constexpr bool value{ true };
constexpr operator bool() const noexcept { return true; }
constexpr bool operator()() const noexcept { return true; }
};
template<typename KeyT, typename ValueT>
struct is_associative_container<std::unordered_map<KeyT, ValueT>> {
using key_type = KeyT;
using value_type = ValueT;
static constexpr bool value{ true };
constexpr operator bool() const noexcept { return true; }
constexpr bool operator()() const noexcept { return true; }
};
/** is_sequence_container */
template<typename T>

Loading…
Cancel
Save