#ifndef TOML11_TRAITS_HPP #define TOML11_TRAITS_HPP #include "from.hpp" #include "into.hpp" #include "compat.hpp" #include "version.hpp" #include #include #include #include #include #include #include #include #if defined(TOML11_HAS_STRING_VIEW) #include #endif #if defined(TOML11_HAS_OPTIONAL) #include #endif namespace toml { inline namespace TOML11_INLINE_VERSION_NAMESPACE { template class basic_value; namespace detail { // --------------------------------------------------------------------------- // check whether type T is a kind of container/map class struct has_iterator_impl { template static std::true_type check(typename T::iterator*); template static std::false_type check(...); }; struct has_value_type_impl { template static std::true_type check(typename T::value_type*); template static std::false_type check(...); }; struct has_key_type_impl { template static std::true_type check(typename T::key_type*); template static std::false_type check(...); }; struct has_mapped_type_impl { template static std::true_type check(typename T::mapped_type*); template static std::false_type check(...); }; struct has_reserve_method_impl { template static std::false_type check(...); template static std::true_type check( decltype(std::declval().reserve(std::declval()))*); }; struct has_push_back_method_impl { template static std::false_type check(...); template static std::true_type check( decltype(std::declval().push_back(std::declval()))*); }; struct is_comparable_impl { template static std::false_type check(...); template static std::true_type check( decltype(std::declval() < std::declval())*); }; struct has_from_toml_method_impl { template static std::true_type check( decltype(std::declval().from_toml(std::declval<::toml::basic_value>()))*); template static std::false_type check(...); }; struct has_into_toml_method_impl { template static std::true_type check(decltype(std::declval().into_toml())*); template static std::false_type check(...); }; struct has_template_into_toml_method_impl { template static std::true_type check(decltype(std::declval().template into_toml())*); template static std::false_type check(...); }; struct has_specialized_from_impl { template static std::false_type check(...); template)> static std::true_type check(::toml::from*); }; struct has_specialized_into_impl { template static std::false_type check(...); template)> static std::true_type check(::toml::into*); }; /// Intel C++ compiler can not use decltype in parent class declaration, here /// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076 #ifdef __INTEL_COMPILER #define decltype(...) std::enable_if::type #endif template struct has_iterator: decltype(has_iterator_impl::check(nullptr)){}; template struct has_value_type: decltype(has_value_type_impl::check(nullptr)){}; template struct has_key_type: decltype(has_key_type_impl::check(nullptr)){}; template struct has_mapped_type: decltype(has_mapped_type_impl::check(nullptr)){}; template struct has_reserve_method: decltype(has_reserve_method_impl::check(nullptr)){}; template struct has_push_back_method: decltype(has_push_back_method_impl::check(nullptr)){}; template struct is_comparable: decltype(is_comparable_impl::check(nullptr)){}; template struct has_from_toml_method: decltype(has_from_toml_method_impl::check(nullptr)){}; template struct has_into_toml_method: decltype(has_into_toml_method_impl::check(nullptr)){}; template struct has_template_into_toml_method: decltype(has_template_into_toml_method_impl::check(nullptr)){}; template struct has_specialized_from: decltype(has_specialized_from_impl::check(nullptr)){}; template struct has_specialized_into: decltype(has_specialized_into_impl::check(nullptr)){}; #ifdef __INTEL_COMPILER #undef decltype #endif // --------------------------------------------------------------------------- // type checkers template struct is_std_pair_impl : std::false_type{}; template struct is_std_pair_impl> : std::true_type{}; template using is_std_pair = is_std_pair_impl>; template struct is_std_tuple_impl : std::false_type{}; template struct is_std_tuple_impl> : std::true_type{}; template using is_std_tuple = is_std_tuple_impl>; template struct is_unordered_set_impl : std::false_type {}; template struct is_unordered_set_impl> : std::true_type {}; template using is_unordered_set = is_unordered_set_impl>; #if defined(TOML11_HAS_OPTIONAL) template struct is_std_optional_impl : std::false_type{}; template struct is_std_optional_impl> : std::true_type{}; template using is_std_optional = is_std_optional_impl>; #else template struct is_std_optional : std::false_type{}; #endif // > C++17 template struct is_std_array_impl : std::false_type{}; template struct is_std_array_impl> : std::true_type{}; template using is_std_array = is_std_array_impl>; template struct is_std_forward_list_impl : std::false_type{}; template struct is_std_forward_list_impl> : std::true_type{}; template using is_std_forward_list = is_std_forward_list_impl>; template struct is_std_basic_string_impl : std::false_type{}; template struct is_std_basic_string_impl> : std::true_type{}; template using is_std_basic_string = is_std_basic_string_impl>; template struct is_1byte_std_basic_string_impl : std::false_type{}; template struct is_1byte_std_basic_string_impl> : std::integral_constant {}; template using is_1byte_std_basic_string = is_std_basic_string_impl>; #if defined(TOML11_HAS_STRING_VIEW) template struct is_std_basic_string_view_impl : std::false_type{}; template struct is_std_basic_string_view_impl> : std::true_type{}; template using is_std_basic_string_view = is_std_basic_string_view_impl>; template struct is_string_view_of : std::false_type {}; template struct is_string_view_of, std::basic_string> : std::true_type {}; #else template struct is_std_basic_string_view : std::false_type {}; template struct is_string_view_of : std::false_type {}; #endif template struct is_chrono_duration_impl: std::false_type{}; template struct is_chrono_duration_impl>: std::true_type{}; template using is_chrono_duration = is_chrono_duration_impl>; template struct is_map_impl : cxx::conjunction< // map satisfies all the following conditions has_iterator, // has T::iterator has_value_type, // has T::value_type has_key_type, // has T::key_type has_mapped_type // has T::mapped_type >{}; template using is_map = is_map_impl>; template struct is_container_impl : cxx::conjunction< cxx::negation>, // not a map cxx::negation>, // not a std::string #ifdef TOML11_HAS_STRING_VIEW cxx::negation>, // not a std::string_view #endif has_iterator, // has T::iterator has_value_type // has T::value_type >{}; template using is_container = is_container_impl>; template struct is_basic_value_impl: std::false_type{}; template struct is_basic_value_impl<::toml::basic_value>: std::true_type{}; template using is_basic_value = is_basic_value_impl>; }// detail } // TOML11_INLINE_VERSION_NAMESPACE } // toml #endif // TOML11_TRAITS_HPP