1// Copyright (c) 2016-2024 Antony Polukhin
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_PFR_DETAIL_DETECTORS_HPP
7#define BOOST_PFR_DETAIL_DETECTORS_HPP
8#pragma once
9
10#include <boost/pfr/detail/config.hpp>
11
12#include <functional>
13#include <type_traits>
14
15namespace boost { namespace pfr { namespace detail {
16///////////////////// `value` is true if Detector<Tleft, Tright> does not compile (SFINAE)
17 struct can_not_apply{};
18
19 template <template <class, class> class Detector, class Tleft, class Tright>
20 struct not_appliable {
21 static constexpr bool value = std::is_same<
22 Detector<Tleft, Tright>,
23 can_not_apply
24 >::value;
25 };
26
27///////////////////// Detectors for different operators
28 template <class S, class T> auto comp_eq_detector_msvc_helper(long) -> decltype(std::declval<S>() == std::declval<T>());
29 template <class S, class T> can_not_apply comp_eq_detector_msvc_helper(int);
30 template <class T1, class T2> using comp_eq_detector = decltype(comp_eq_detector_msvc_helper<T1,T2>(1L));
31
32 template <class S, class T> auto comp_ne_detector_msvc_helper(long) -> decltype(std::declval<S>() != std::declval<T>());
33 template <class S, class T> can_not_apply comp_ne_detector_msvc_helper(int);
34 template <class T1, class T2> using comp_ne_detector = decltype(comp_ne_detector_msvc_helper<T1,T2>(1L));
35
36 template <class S, class T> auto comp_lt_detector_msvc_helper(long) -> decltype(std::declval<S>() < std::declval<T>());
37 template <class S, class T> can_not_apply comp_lt_detector_msvc_helper(int);
38 template <class T1, class T2> using comp_lt_detector = decltype(comp_lt_detector_msvc_helper<T1,T2>(1L));
39
40 template <class S, class T> auto comp_le_detector_msvc_helper(long) -> decltype(std::declval<S>() <= std::declval<T>());
41 template <class S, class T> can_not_apply comp_le_detector_msvc_helper(int);
42 template <class T1, class T2> using comp_le_detector = decltype(comp_le_detector_msvc_helper<T1,T2>(1L));
43
44 template <class S, class T> auto comp_gt_detector_msvc_helper(long) -> decltype(std::declval<S>() > std::declval<T>());
45 template <class S, class T> can_not_apply comp_gt_detector_msvc_helper(int);
46 template <class T1, class T2> using comp_gt_detector = decltype(comp_gt_detector_msvc_helper<T1,T2>(1L));
47
48 template <class S, class T> auto comp_ge_detector_msvc_helper(long) -> decltype(std::declval<S>() >= std::declval<T>());
49 template <class S, class T> can_not_apply comp_ge_detector_msvc_helper(int);
50 template <class T1, class T2> using comp_ge_detector = decltype(comp_ge_detector_msvc_helper<T1,T2>(1L));
51
52
53 template <class S> auto hash_detector_msvc_helper(long) -> decltype(std::hash<S>{}(std::declval<S>()));
54 template <class S> can_not_apply hash_detector_msvc_helper(int);
55 template <class T1, class T2> using hash_detector = decltype(hash_detector_msvc_helper<T1,T2>(1L));
56
57
58 template <class S, class T> auto ostreamable_detector_msvc_helper(long) -> decltype(std::declval<S>() << std::declval<T>());
59 template <class S, class T> can_not_apply ostreamable_detector_msvc_helper(int);
60 template <class S, class T> using ostreamable_detector = decltype(ostreamable_detector_msvc_helper<S,T>(1L));
61
62 template <class S, class T> auto istreamable_detector_msvc_helper(long) -> decltype(std::declval<S>() >> std::declval<T>());
63 template <class S, class T> can_not_apply istreamable_detector_msvc_helper(int);
64 template <class S, class T> using istreamable_detector = decltype(istreamable_detector_msvc_helper<S,T>(1L));
65
66}}} // namespace boost::pfr::detail
67
68#endif // BOOST_PFR_DETAIL_DETECTORS_HPP
69
70
71

source code of boost/libs/pfr/include/boost/pfr/detail/detectors.hpp