xref: /llvm-project/libcxx/test/support/operator_hijacker.h (revision 09e3a360581dc36d0820d3fb6da9bd7cfed87b5d)
1b8608b87SMark de Wever //===----------------------------------------------------------------------===//
2b8608b87SMark de Wever //
3b8608b87SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b8608b87SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5b8608b87SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b8608b87SMark de Wever //
7b8608b87SMark de Wever //===----------------------------------------------------------------------===//
8b8608b87SMark de Wever 
9b8608b87SMark de Wever #ifndef SUPPORT_OPERATOR_HIJACKER_H
10b8608b87SMark de Wever #define SUPPORT_OPERATOR_HIJACKER_H
11b8608b87SMark de Wever 
12b8608b87SMark de Wever #include <cstddef>
13b8608b87SMark de Wever #include <functional>
14*09e3a360SLouis Dionne #include <memory>
154dee6411SMark de Wever #include <string>
16*09e3a360SLouis Dionne #include <type_traits>
17b8608b87SMark de Wever 
18b8608b87SMark de Wever #include "test_macros.h"
19b8608b87SMark de Wever 
20b8608b87SMark de Wever /// Helper struct to test ADL-hijacking in containers.
21b8608b87SMark de Wever ///
22b8608b87SMark de Wever /// The class has some additional operations to be usable in all containers.
23b8608b87SMark de Wever struct operator_hijacker {
244dee6411SMark de Wever   TEST_CONSTEXPR bool operator<(const operator_hijacker&) const { return true; }
254dee6411SMark de Wever   TEST_CONSTEXPR bool operator==(const operator_hijacker&) const { return true; }
26b8608b87SMark de Wever 
27b8608b87SMark de Wever   template <typename T>
28b8608b87SMark de Wever   friend void operator&(T&&) = delete;
29b8608b87SMark de Wever   template <class T, class U>
30b8608b87SMark de Wever   friend void operator,(T&&, U&&) = delete;
31b8608b87SMark de Wever   template <class T, class U>
32b8608b87SMark de Wever   friend void operator&&(T&&, U&&) = delete;
33b8608b87SMark de Wever   template <class T, class U>
34b8608b87SMark de Wever   friend void operator||(T&&, U&&) = delete;
35b8608b87SMark de Wever };
36b8608b87SMark de Wever 
37f41f3925SMark de Wever static_assert(std::is_trivially_copyable<operator_hijacker>::value &&     //
38f41f3925SMark de Wever                   std::is_copy_constructible<operator_hijacker>::value && //
39f41f3925SMark de Wever                   std::is_move_constructible<operator_hijacker>::value && //
40f41f3925SMark de Wever                   std::is_copy_assignable<operator_hijacker>::value &&    //
41f41f3925SMark de Wever                   std::is_move_assignable<operator_hijacker>::value,      //
42f41f3925SMark de Wever               "does not satisfy the requirements for atomic<operator_hijacker>");
43f41f3925SMark de Wever 
44b8608b87SMark de Wever template <>
45b8608b87SMark de Wever struct std::hash<operator_hijacker> {
46fb855eb9SMark de Wever   std::size_t operator()(const operator_hijacker&) const { return 0; }
47b8608b87SMark de Wever };
48b8608b87SMark de Wever 
494dee6411SMark de Wever template <class T>
504dee6411SMark de Wever struct operator_hijacker_allocator : std::allocator<T>, operator_hijacker {
514dee6411SMark de Wever #if TEST_STD_VER <= 17
524dee6411SMark de Wever   struct rebind {
534dee6411SMark de Wever     typedef operator_hijacker_allocator<T> other;
544dee6411SMark de Wever   };
554dee6411SMark de Wever #endif
564dee6411SMark de Wever };
574dee6411SMark de Wever 
584dee6411SMark de Wever template <class CharT>
594dee6411SMark de Wever struct operator_hijacker_char_traits : std::char_traits<CharT>, operator_hijacker {};
604dee6411SMark de Wever 
61b8608b87SMark de Wever #endif // SUPPORT_OPERATOR_HIJACKER_H
62