1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
24 #include "arrow/type_traits.h"
29 // Atomic shared_ptr operations only appeared in libstdc++ since GCC 5,
30 // emulate them with unsafe ops if unavailable.
31 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57250
33 template <typename T
, typename
= void>
34 struct is_atomic_load_shared_ptr_available
: std::false_type
{};
37 struct is_atomic_load_shared_ptr_available
<
38 T
, void_t
<decltype(std::atomic_load(std::declval
<const std::shared_ptr
<T
>*>()))>>
42 using enable_if_atomic_load_shared_ptr_available
=
43 enable_if_t
<is_atomic_load_shared_ptr_available
<T
>::value
, T
>;
46 using enable_if_atomic_load_shared_ptr_unavailable
=
47 enable_if_t
<!is_atomic_load_shared_ptr_available
<T
>::value
, T
>;
50 enable_if_atomic_load_shared_ptr_available
<std::shared_ptr
<T
>> atomic_load(
51 const std::shared_ptr
<T
>* p
) {
52 return std::atomic_load(p
);
56 enable_if_atomic_load_shared_ptr_unavailable
<std::shared_ptr
<T
>> atomic_load(
57 const std::shared_ptr
<T
>* p
) {
61 template <typename T
, typename
= void>
62 struct is_atomic_store_shared_ptr_available
: std::false_type
{};
65 struct is_atomic_store_shared_ptr_available
<
66 T
, void_t
<decltype(std::atomic_store(std::declval
<std::shared_ptr
<T
>*>(),
67 std::declval
<std::shared_ptr
<T
>>()))>>
71 using enable_if_atomic_store_shared_ptr_available
=
72 enable_if_t
<is_atomic_store_shared_ptr_available
<T
>::value
, T
>;
75 using enable_if_atomic_store_shared_ptr_unavailable
=
76 enable_if_t
<!is_atomic_store_shared_ptr_available
<T
>::value
, T
>;
79 void atomic_store(enable_if_atomic_store_shared_ptr_available
<std::shared_ptr
<T
>*> p
,
80 std::shared_ptr
<T
> r
) {
81 std::atomic_store(p
, std::move(r
));
85 void atomic_store(enable_if_atomic_store_shared_ptr_unavailable
<std::shared_ptr
<T
>*> p
,
86 std::shared_ptr
<T
> r
) {
91 bool atomic_compare_exchange_strong(
92 enable_if_atomic_store_shared_ptr_available
<std::shared_ptr
<T
>*> p
,
93 std::shared_ptr
<T
>* expected
, std::shared_ptr
<T
> desired
) {
94 return std::atomic_compare_exchange_strong(p
, expected
, std::move(desired
));
98 bool atomic_compare_exchange_strong(
99 enable_if_atomic_store_shared_ptr_unavailable
<std::shared_ptr
<T
>*> p
,
100 std::shared_ptr
<T
>* expected
, std::shared_ptr
<T
> desired
) {
101 if (*p
== *expected
) {
102 *p
= std::move(desired
);
110 } // namespace internal