Program Listing for File type-traits.hpp
↰ Return to documentation for file (zeep/type-traits.hpp
)
// Copyright Maarten L. Hekkelman, 2014-2023
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#include <zeep/config.hpp>
#if __has_include(<experimental/type_traits>)
#include <experimental/type_traits>
#else
#include <type_traits>
#endif
#include <zeep/value-serializer.hpp>
#if (not defined(__cpp_lib_experimental_detect) or (__cpp_lib_experimental_detect < 201505)) and (not defined(_LIBCPP_VERSION) or _LIBCPP_VERSION < 5000)
// This code is copied from:
// https://ld2015.scusa.lsu.edu/cppreference/en/cpp/experimental/is_detected.html
namespace std
{
template< class... >
using void_t = void;
namespace experimental
{
namespace detail
{
template <class Default, class AlwaysVoid,
template<class...> class Op, class... Args>
struct detector
{
using value_t = false_type;
using type = Default;
};
template <class Default, template<class...> class Op, class... Args>
struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
// Note that std::void_t is a c++17 feature
using value_t = true_type;
using type = Op<Args...>;
};
} // namespace detail
struct nonesuch
{
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;
};
template <template<class...> class Op, class... Args>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
template <template<class...> class Op, class... Args>
constexpr inline bool is_detected_v = is_detected<Op,Args...>::value;
template <template<class...> class Op, class... Args>
using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
template <class Default, template<class...> class Op, class... Args>
using detected_or = detail::detector<Default, void, Op, Args...>;
template <class Expected, template <class...> class Op, class... Args>
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
template <class Expected, template<class...> class Op, class... Args>
constexpr inline bool is_detected_exact_v = is_detected_exact<Expected, Op, Args...>::value;
}
}
#endif
namespace zeep
{
template <typename T>
using value_type_t = typename T::value_type;
template <typename T>
using key_type_t = typename T::key_type;
template <typename T>
using mapped_type_t = typename T::mapped_type;
template <typename T>
using iterator_t = typename T::iterator;
template <typename T>
using iterator_category_t = typename T::iterator_category;
template <typename T>
using difference_type_t = typename T::difference_type;
template <typename T>
using reference_t = typename T::reference;
template <typename T>
using pointer_t = typename T::pointer;
template<typename T, typename = void>
struct is_complete_type : std::false_type {};
template<typename T>
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
template<typename T>
inline constexpr bool is_complete_type_v = is_complete_type<T>::value;
template<typename T>
using std_string_npos_t = decltype(T::npos);
template<typename T>
using serialize_value_t = decltype(std::declval<value_serializer<T>&>().from_string(std::declval<const std::string&>()));
template<typename T, typename Archive>
using serialize_function = decltype(std::declval<T&>().serialize(std::declval<Archive&>(), std::declval<unsigned long>()));
template<typename T, typename Archive, typename = void>
struct has_serialize : std::false_type {};
template<typename T, typename Archive>
struct has_serialize<T, Archive, typename std::enable_if_t<std::is_class_v<T>>>
{
static constexpr bool value = std::experimental::is_detected_v<serialize_function,T,Archive>;
};
template<typename T, typename S>
inline constexpr bool has_serialize_v = has_serialize<T, S>::value;
template<typename T, typename S>
struct is_serializable_type
{
using value_type = std::remove_const_t<typename std::remove_reference_t<T>>;
static constexpr bool value =
std::experimental::is_detected_v<serialize_value_t,value_type> or
has_serialize_v<value_type,S>;
};
template<typename T, typename S>
inline constexpr bool is_serializable_type_v = is_serializable_type<T,S>::value;
template<typename T>
using vs_to_string_function = decltype(zeep::value_serializer<T>::to_string(std::declval<T&>()));
template<typename T>
using vs_from_string_function = decltype(zeep::value_serializer<T>::from_string(std::declval<const std::string&>()));
template<typename T, typename = void>
struct has_value_serializer : std::false_type {};
template<typename T>
struct has_value_serializer<T>
{
static constexpr bool value =
std::experimental::is_detected_v<vs_to_string_function,T> and
std::experimental::is_detected_v<vs_from_string_function,T>;
};
template<typename T>
inline constexpr bool has_value_serializer_v = has_value_serializer<T>::value;
template<typename T, typename S, typename = void>
struct is_serializable_array_type : std::false_type {};
template<typename T, typename S>
struct is_serializable_array_type<T, S,
std::enable_if_t<
std::experimental::is_detected_v<value_type_t, T> and
std::experimental::is_detected_v<iterator_t, T> and
not std::experimental::is_detected_v<std_string_npos_t, T>>>
{
static constexpr bool value = is_serializable_type_v<typename T::value_type,S>;
};
template<typename T, typename S>
inline constexpr bool is_serializable_array_type_v = is_serializable_array_type<T,S>::value;
}