diff --git a/src/common/app_parameters.cpp b/src/common/app_parameters.cpp index 83a392b..95a729f 100644 --- a/src/common/app_parameters.cpp +++ b/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 values_map; - for (auto& value : m_values) { - values_map.emplace(value.first, value.second); - } - return std::map{ { "Path", m_path }, { "Args", m_args }, { "Switches", m_switches }, - { "Values", values_map } + { "Values", m_values } }; } diff --git a/src/include/object.hpp b/src/include/object.hpp index 70453be..169bd37 100644 --- a/src/include/object.hpp +++ b/src/include/object.hpp @@ -71,8 +71,9 @@ public: }; template - struct is_backing::value>::type> { - static constexpr bool value = true; + struct is_backing::value>::type> { + static constexpr bool value = std::is_same::key_type, std::string>::value + && std::is_same::value_type, object>::value; using type = map_t; }; @@ -97,7 +98,8 @@ public: // Value constructors template::type>::value - && !is_sequence_container::type>::value>::type* = nullptr> + && !is_sequence_container::type>::value + && (!is_associative_container::type>::value || std::is_same::type, map_t>::value)>::type* = nullptr> object(T&& in_value) : m_value{ typename is_backing::type>::type{ std::forward(in_value) } } { // Empty ctor body @@ -124,6 +126,30 @@ public: } } + // std::unordered_map + template::type>::value + && std::is_same::type>::key_type, std::string>::value + && std::is_same::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) + template::type>::value + && (std::is_convertible::type>::key_type, std::string>::value + || std::is_convertible::type>::key_type, std::string_view>::value) + && !std::is_same::type>::value_type, object>::value>::type* = nullptr> + object(T&& in_value) + : m_value{ map_t{} } { + auto& map = std::get(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); diff --git a/src/include/type_traits.hpp b/src/include/type_traits.hpp index 4239e08..af6242f 100644 --- a/src/include/type_traits.hpp +++ b/src/include/type_traits.hpp @@ -30,6 +30,13 @@ namespace jessilib { +/** remove_cvref (can be replaced with C++20) */ + +template +struct remove_cvref { + typedef std::remove_cv_t> type; +}; + /** is_vector */ template @@ -108,7 +115,7 @@ struct is_unordered_set> { constexpr bool operator()() const noexcept { return true; } }; -/** is_unordered_set */ +/** is_unordered_multiset */ template struct is_unordered_multiset : std::false_type {}; @@ -121,6 +128,57 @@ struct is_unordered_multiset> { constexpr bool operator()() const noexcept { return true; } }; +/** is_map */ + +template +struct is_map : std::false_type {}; + +template +struct is_map> { + 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 +struct is_unordered_map : std::false_type {}; + +template +struct is_unordered_map> { + 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 +struct is_associative_container : std::false_type {}; + +template +struct is_associative_container> { + 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 +struct is_associative_container> { + 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