Skip to content

Commit

Permalink
Create atomic headers
Browse files Browse the repository at this point in the history
  • Loading branch information
lackhole committed Feb 28, 2025
1 parent 438cb89 commit d0f1848
Show file tree
Hide file tree
Showing 12 changed files with 372 additions and 7 deletions.
57 changes: 57 additions & 0 deletions include/preview/__atomic/atomic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Created by yonggyulee on 2024. 7. 18.
//

#ifndef PREVIEW_ATOMIC_ATOMIC_H_
#define PREVIEW_ATOMIC_ATOMIC_H_

#include <type_traits>

#include "preview/__atomic/detail/atomic_floating_point.h"
#include "preview/__atomic/detail/atomic_generic.h"
#include "preview/__atomic/detail/atomic_integral.h"
#include "preview/__atomic/detail/atomic_pointer.h"
#include "preview/__type_traits/disjunction.h"
#include "preview/__type_traits/conditional.h"

namespace preview {
namespace detail {

template<typename T, bool = disjunction<std::is_integral<T>, std::is_floating_point<T>>::value>
struct atomic_difference_type {};
template<typename T>
struct atomic_difference_type<T, true> { using type = T; };

template<typename T>
using atomic_base_t = conditional_t<
std::is_integral<T>, atomic_integral<T>,
std::is_floating_point<T>, atomic_floating_point<T>,
std::is_pointer<T>, atomic_pointer<T>,
atomic_generic<T>
>;

} // namespace detail

template<typename T>
class atomic : public detail::atomic_base_t<T> {
using base = detail::atomic_base_t<T>;
public:
using base::base;

T operator=(T desired) noexcept {
this->store(desired);
return desired;
}

T operator=(T desired) volatile noexcept {
this->store(desired);
return desired;
}

atomic<T>& operator=(const atomic<T>& other) = delete;
atomic<T>& operator=(const atomic<T>& other) volatile = delete;
};

} // namespace preview

#endif // PREVIEW_ATOMIC_ATOMIC_H_
12 changes: 12 additions & 0 deletions include/preview/__atomic/atomic_notify_all.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Created by yonggyulee on 2024. 7. 19.
//

#ifndef PREVIEW_ATOMIC_ATOMIC_NOTIFY_ALL_H_
#define PREVIEW_ATOMIC_ATOMIC_NOTIFY_ALL_H_

namespace preview {

} // namespace preview

#endif // PREVIEW_ATOMIC_ATOMIC_NOTIFY_ALL_H_
12 changes: 12 additions & 0 deletions include/preview/__atomic/atomic_notify_one.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Created by yonggyulee on 2024. 7. 19.
//

#ifndef PREVIEW_ATOMIC_ATOMIC_NOTIFY_ONE_H_
#define PREVIEW_ATOMIC_ATOMIC_NOTIFY_ONE_H_

namespace preview {

} // namespace preview

#endif // PREVIEW_ATOMIC_ATOMIC_NOTIFY_ONE_H_
43 changes: 43 additions & 0 deletions include/preview/__atomic/atomic_wait.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Created by yonggyulee on 2024. 7. 19.
//

#ifndef PREVIEW_ATOMIC_ATOMIC_WAIT_H_
#define PREVIEW_ATOMIC_ATOMIC_WAIT_H_

#include <atomic>
#include <cassert>

#include "preview/__atomic/atomic.h"

namespace preview {

template<typename T>
void atomic_wait(const atomic<T>* object, typename atomic<T>::value_type old) {
object->wait(old);
}

template<typename T>
void atomic_wait(const volatile atomic<T>* object, typename atomic<T>::value_type old) {
object->wait(old);
}

template<typename T>
void atomic_wait_explicit(const atomic<T>* object, typename atomic<T>::value_type old, std::memory_order order) {
assert(order != std::memory_order_relaxed);
assert(order != std::memory_order_acq_rel);

object->wait(old, order);
}

template<typename T>
void atomic_wait_explicit(const volatile atomic<T>* object, typename atomic<T>::value_type old, std::memory_order order) {
assert(order != std::memory_order_relaxed);
assert(order != std::memory_order_acq_rel);

object->wait(old, order);
}

} // namespace preview

#endif // PREVIEW_ATOMIC_ATOMIC_WAIT_H_
24 changes: 24 additions & 0 deletions include/preview/__atomic/detail/atomic_floating_point.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Created by yonggyulee on 2024. 9. 2.
//

#ifndef PREVIEW_ATOMIC_DETAIL_ATOMIC_FLOATING_POINT_H_
#define PREVIEW_ATOMIC_DETAIL_ATOMIC_FLOATING_POINT_H_

#include "preview/__atomic/detail/cxx20_atomic_base.h"

namespace preview {
namespace detail {

template<typename T>
struct atomic_floating_point : public cxx20_atomic_base<T> {
using value_type = T;
using difference_type = value_type;

using cxx20_atomic_base<T>::cxx20_atomic_base;
};

} // namespace detail
} // namespace preview

#endif // PREVIEW_ATOMIC_DETAIL_ATOMIC_FLOATING_POINT_H_
19 changes: 19 additions & 0 deletions include/preview/__atomic/detail/atomic_generic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Created by yonggyulee on 2024. 9. 2.
//

#ifndef PREVIEW_ATOMIC_DETAIL_ATOMIC_GENERIC_H_
#define PREVIEW_ATOMIC_DETAIL_ATOMIC_GENERIC_H_

#include "preview/__atomic/detail/cxx20_atomic_base.h"

namespace preview {
namespace detail {

template<typename T>
struct atomic_generic : cxx20_atomic_base<T> {};

} // namespace detail
} // namespace preview

#endif // PREVIEW_ATOMIC_DETAIL_ATOMIC_GENERIC_H_
27 changes: 27 additions & 0 deletions include/preview/__atomic/detail/atomic_integral.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Created by yonggyulee on 2024. 9. 2.
//

#ifndef PREVIEW_ATOMIC_DETAIL_ATOMIC_INTEGRAL_H_
#define PREVIEW_ATOMIC_DETAIL_ATOMIC_INTEGRAL_H_

#include "preview/__atomic/detail/cxx20_atomic_base.h"

namespace preview {
namespace detail {

template<typename T>
class atomic_integral : public cxx20_atomic_base<T> {
public:
using cxx20_atomic_base<T>::cxx20_atomic_base;

// TODO: Implement fetch_max
// T fetch_max(T operand, std::memory_order order = std::memory_order_seq_cst) noexcept {}
// T fetch_max(T operand, std::memory_order order = std::memory_order_seq_cst) volatile noexcept {}

};

} // namespace detail
} // namespace preview

#endif // PREVIEW_ATOMIC_DETAIL_ATOMIC_INTEGRAL_H_
24 changes: 24 additions & 0 deletions include/preview/__atomic/detail/atomic_pointer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Created by yonggyulee on 2024. 9. 2.
//

#ifndef PREVIEW_ATOMIC_DETAIL_ATOMIC_POINTER_H_
#define PREVIEW_ATOMIC_DETAIL_ATOMIC_POINTER_H_

#include "preview/__atomic/detail/cxx20_atomic_base.h"

namespace preview {
namespace detail {

template<typename T>
struct atomic_pointer : public cxx20_atomic_base<T> {

// TODO: Implement fetch_max
// T fetch_max(T operand, std::memory_order order = std::memory_order_seq_cst) noexcept {}
// T fetch_max(T operand, std::memory_order order = std::memory_order_seq_cst) volatile noexcept {}
};

} // namespace detail
} // namespace preview

#endif // PREVIEW_ATOMIC_DETAIL_ATOMIC_POINTER_H_
67 changes: 67 additions & 0 deletions include/preview/__atomic/detail/cxx20_atomic_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// Created by yonggyulee on 2024. 9. 2.
//

#ifndef PREVIEW_ATOMIC_DETAIL_ATOMIC_BASE_H_
#define PREVIEW_ATOMIC_DETAIL_ATOMIC_BASE_H_

#include <atomic>
#include <type_traits>

#include "preview/config.h"

#if PREVIEW_USE_BOOST_ATOMIC
#include "boost/atomic.hpp"
#endif

#include "preview/__type_traits/conjunction.h"
#include "preview/__type_traits/has_typename_difference_type.h"
#include "preview/__type_traits/void_t.h"

namespace preview {
namespace detail {

template<typename T, typename = void>
struct has_member_function_wait : std::false_type {};
template<typename T>
struct has_member_function_wait<T, void_t<decltype(std::declval<T>().wait(std::declval<T>(), std::declval<std::memory_order>()))>> : std::true_type {};

template<typename T, typename = void>
struct has_member_function_notify_one : std::false_type {};
template<typename T>
struct has_member_function_notify_one<T, void_t<decltype(std::declval<T>().notify_one())>> : std::true_type {};

template<typename T, typename = void>
struct has_member_function_notify_all : std::false_type {};
template<typename T>
struct has_member_function_notify_all<T, void_t<decltype(std::declval<T>().notify_all())>> : std::true_type {};

template<typename T>
struct has_wait_and_notify : conjunction<
has_member_function_wait<T>,
has_member_function_notify_one<T>,
has_member_function_notify_all<T>
> {};

template<typename T>
struct is_cxx20_atomic : conjunction<
has_wait_and_notify<T>,
has_typename_difference_type<T>
> {};

template<typename T>
using cxx20_atomic_base =
#if PREVIEW_USE_BOOST_ATOMIC
boost::atomic<T>;
#else
std::atomic<T>;
static_assert(is_cxx20_atomic<std::atomic<int>>::value,
"std::atomic<T> does not conform C++20 standard. Set PREVIEW_USE_BOOST_ATOMIC to 1");
#endif



} // namespace detail
} // namespace preview

#endif // PREVIEW_ATOMIC_DETAIL_ATOMIC_BASE_H_
13 changes: 13 additions & 0 deletions include/preview/atomic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Created by yonggyulee on 2024. 7. 18.
//

#ifndef PREVIEW_ATOMIC_H_
#define PREVIEW_ATOMIC_H_

#include "preview/__atomic/atomic.h"
#include "preview/__atomic/atomic_notify_all.h"
#include "preview/__atomic/atomic_notify_one.h"
#include "preview/__atomic/atomic_wait.h"

#endif // PREVIEW_ATOMIC_H_
29 changes: 22 additions & 7 deletions include/preview/cmake_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,33 @@

#include "preview/core.h"

# if PREVIEW_CXX_VERSION >= 20 && \
(!defined(__clang_major__) || (defined(__clang_major__) && __clang_major__ > 11)) && \
(!defined(PREVIEW_NDK_VERSION_MAJOR) || PREVIEW_NDK_VERSION_MAJOR >= 26)
# define PREVIEW_CONFORM_CXX20_STANDARD 1
# else
# define PREVIEW_CONFORM_CXX20_STANDARD 0
# endif
#if PREVIEW_CXX_VERSION >= 20 && \
(!defined(__clang_major__) || (defined(__clang_major__) && __clang_major__ > 11)) && \
(!defined(PREVIEW_NDK_VERSION_MAJOR) || PREVIEW_NDK_VERSION_MAJOR >= 26)
# define PREVIEW_CONFORM_CXX20_STANDARD 1
#else
# define PREVIEW_CONFORM_CXX20_STANDARD 0
#endif

#ifdef PREVIEW_CMAKE_CONFIG
# cmakedefine PREVIEW_CONFIGURED_CXX_VERSION ${CMAKE_CXX_STANDARD}
# if PREVIEW_CONFIGURED_CXX_VERSION != PREVIEW_CXX_VERSION
# warning "STL-Preview is configured for different C++ standard version"
# else
# define PREVIEW_USE_CMAKE_CONFIG
# endif
#endif

#ifdef PREVIEW_USE_CMAKE_CONFIG

#cmakedefine01 PREVIEW_HAVE_BUILTIN_BIT_CAST
#cmakedefine01 PREVIEW_HAVE_BUILTIN_CONSTEXPR_ADDRESSOF

#cmakedefine01 PREVIEW_HAVE_STRING_VIEW
#cmakedefine01 PREVIEW_HAVE_CONTIGUOUS_ITERATOR_TAG

#cmakedefine01 PREVIEW_USE_BOOST_ATOMIC

#else

#define PREVIEW_HAVE_BUILTIN_BIT_CAST PREVIEW_CONFORM_CXX20_STANDARD
Expand All @@ -28,4 +39,8 @@
#define PREVIEW_HAVE_CONTIGUOUS_ITERATOR_TAG PREVIEW_CONFORM_CXX20_STANDARD
#define PREVIEW_HAVE_STRING_VIEW (PREVIEW_CXX_VERSION >= 17)

#ifndef PREVIEW_USE_BOOST_ATOMIC
# define PREVIEW_USE_BOOST_ATOMIC (PREVIEW_CXX_VERSION < 20)
#endif

#endif
Loading

0 comments on commit d0f1848

Please sign in to comment.