1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <functional>
10 
11 // namespace placeholders {
12 //   // M is the implementation-defined number of placeholders
13 //   extern unspecified _1;
14 //   extern unspecified _2;
15 //   .
16 //   .
17 //   .
18 //   extern unspecified _Mp;
19 // }
20 
21 // The Standard recommends implementing them as `inline constexpr` in C++17.
22 //
23 // Libc++ implements the placeholders as `extern const` in all standard modes
24 // to avoid an ABI break in C++03: making them `inline constexpr` requires removing
25 // their definition in the shared library to avoid ODR violations, which is an
26 // ABI break.
27 //
28 // Concretely, `extern const` is almost indistinguishable from constexpr for the
29 // placeholders since they are empty types.
30 
31 #include <functional>
32 #include <type_traits>
33 
34 #include "test_macros.h"
35 
36 template <class T>
test(const T & t)37 TEST_CONSTEXPR_CXX17 void test(const T& t) {
38   // Test default constructible.
39   {
40     T x; (void)x;
41   }
42 
43   // Test copy constructible.
44   {
45     T x = t; (void)x;
46     static_assert(std::is_nothrow_copy_constructible<T>::value, "");
47     static_assert(std::is_nothrow_move_constructible<T>::value, "");
48   }
49 
50   // It is implementation-defined whether placeholder types are CopyAssignable.
51   // CopyAssignable placeholders' copy assignment operators shall not throw exceptions.
52 #ifdef _LIBCPP_VERSION
53   {
54     T x;
55     x = t;
56     static_assert(std::is_nothrow_copy_assignable<T>::value, "");
57     static_assert(std::is_nothrow_move_assignable<T>::value, "");
58   }
59 #endif
60 }
61 
test_all()62 TEST_CONSTEXPR_CXX17 bool test_all() {
63   test(std::placeholders::_1);
64   test(std::placeholders::_2);
65   test(std::placeholders::_3);
66   test(std::placeholders::_4);
67   test(std::placeholders::_5);
68   test(std::placeholders::_6);
69   test(std::placeholders::_7);
70   test(std::placeholders::_8);
71   test(std::placeholders::_9);
72   test(std::placeholders::_10);
73   return true;
74 }
75 
main(int,char **)76 int main(int, char**) {
77   test_all();
78 #if TEST_STD_VER >= 17
79   static_assert(test_all(), "");
80 #endif
81 
82   return 0;
83 }
84