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 #ifndef _LIBCPP___ATOMIC_MEMORY_ORDER_H
10 #define _LIBCPP___ATOMIC_MEMORY_ORDER_H
11 
12 #include <__config>
13 #include <__type_traits/is_same.h>
14 #include <__type_traits/underlying_type.h>
15 
16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17 #  pragma GCC system_header
18 #endif
19 
20 _LIBCPP_BEGIN_NAMESPACE_STD
21 
22 // Figure out what the underlying type for `memory_order` would be if it were
23 // declared as an unscoped enum (accounting for -fshort-enums). Use this result
24 // to pin the underlying type in C++20.
25 enum __legacy_memory_order {
26     __mo_relaxed,
27     __mo_consume,
28     __mo_acquire,
29     __mo_release,
30     __mo_acq_rel,
31     __mo_seq_cst
32 };
33 
34 using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type;
35 
36 #if _LIBCPP_STD_VER >= 20
37 
38 enum class memory_order : __memory_order_underlying_t {
39   relaxed = __mo_relaxed,
40   consume = __mo_consume,
41   acquire = __mo_acquire,
42   release = __mo_release,
43   acq_rel = __mo_acq_rel,
44   seq_cst = __mo_seq_cst
45 };
46 
47 static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
48   "unexpected underlying type for std::memory_order");
49 
50 inline constexpr auto memory_order_relaxed = memory_order::relaxed;
51 inline constexpr auto memory_order_consume = memory_order::consume;
52 inline constexpr auto memory_order_acquire = memory_order::acquire;
53 inline constexpr auto memory_order_release = memory_order::release;
54 inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
55 inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
56 
57 #else
58 
59 enum memory_order {
60   memory_order_relaxed = __mo_relaxed,
61   memory_order_consume = __mo_consume,
62   memory_order_acquire = __mo_acquire,
63   memory_order_release = __mo_release,
64   memory_order_acq_rel = __mo_acq_rel,
65   memory_order_seq_cst = __mo_seq_cst,
66 };
67 
68 #endif // _LIBCPP_STD_VER >= 20
69 
70 _LIBCPP_END_NAMESPACE_STD
71 
72 #endif // _LIBCPP___ATOMIC_MEMORY_ORDER_H
73