1+ /*
2+ * Copyright 2023 The Nodepp Project Authors. All Rights Reserved.
3+ *
4+ * Licensed under the MIT (the "License"). You may not use
5+ * this file except in compliance with the License. You can obtain a copy
6+ * in the file LICENSE in the source distribution or at
7+ * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE
8+ */
9+
10+ /* ────────────────────────────────────────────────────────────────────────────*/
11+
12+ #ifndef NODEPP_POSIX_ATOMIC
13+ #define NODEPP_POSIX_ATOMIC
14+
15+ /* ────────────────────────────────────────────────────────────────────────────*/
16+
17+ #include < stdbool.h>
18+
19+ /* ────────────────────────────────────────────────────────────────────────────*/
20+
21+ namespace nodepp { namespace atomic {
22+
23+ template < class T > struct is_atomic : type::false_type{};
24+
25+ template <> struct is_atomic <int > : type::true_type {};
26+ template <> struct is_atomic <uint> : type::true_type {};
27+ template <> struct is_atomic <bool > : type::true_type {};
28+ template <> struct is_atomic <char > : type::true_type {};
29+ template <> struct is_atomic <long > : type::true_type {};
30+ template <> struct is_atomic <short > : type::true_type {};
31+ template <> struct is_atomic <uchar> : type::true_type {};
32+ template <> struct is_atomic <llong> : type::true_type {};
33+ template <> struct is_atomic <ulong> : type::true_type {};
34+ template <> struct is_atomic <ushort> : type::true_type {};
35+ template <> struct is_atomic <ullong> : type::true_type {};
36+
37+ // template<> struct is_atomic<float> : type::true_type {};
38+ // template<> struct is_atomic<double> : type::true_type {};
39+
40+ template <> struct is_atomic <wchar_t > : type::true_type {};
41+ template <> struct is_atomic <char16_t > : type::true_type {};
42+ template <> struct is_atomic <char32_t > : type::true_type {};
43+
44+ template < class T > struct is_atomic <T*> : type::true_type{};
45+
46+ }}
47+
48+ /* ────────────────────────────────────────────────────────────────────────────*/
49+
50+ namespace nodepp {
51+ template < class T , class = typename type::enable_if<atomic::is_atomic<T>::value,T>::type >
52+ class atomic_t { private: T value; protected:
53+
54+ void cpy ( const atomic_t & other ) noexcept {
55+ memcpy ( &value, &other.value , sizeof ( T ) );
56+ }
57+
58+ void mve ( atomic_t && other ) noexcept {
59+ memmove ( &value, &other.value , sizeof ( T ) );
60+ }
61+
62+ public:
63+
64+ atomic_t ( atomic_t && other ) noexcept { mve (type::move (other)); }
65+
66+ atomic_t ( const atomic_t & other ) noexcept { cpy (other); }
67+
68+ atomic_t ( T _val_ ) noexcept : value( _val_ ) {}
69+
70+ atomic_t () noexcept : value( T{} ) {}
71+
72+ public:
73+
74+ T get () const noexcept {
75+ return __atomic_load_n ( &value, __ATOMIC_ACQUIRE );
76+ }
77+
78+ void set ( T new_val ) noexcept {
79+ __atomic_store_n ( &value, new_val, __ATOMIC_RELEASE );
80+ }
81+
82+ T sub ( T new_val ) noexcept {
83+ return __atomic_fetch_sub ( &value, new_val, __ATOMIC_SEQ_CST );
84+ }
85+
86+ T _and ( T new_val ) noexcept {
87+ return __atomic_fetch_and ( &value, new_val, __ATOMIC_SEQ_CST );
88+ }
89+
90+ T _xor ( T new_val ) noexcept {
91+ return __atomic_fetch_xor ( &value, new_val, __ATOMIC_SEQ_CST );
92+ }
93+
94+ T _or ( T new_val ) noexcept {
95+ return __atomic_fetch_or ( &value, new_val, __ATOMIC_SEQ_CST );
96+ }
97+
98+ T add ( T new_val ) noexcept {
99+ return __atomic_fetch_add ( &value, new_val, __ATOMIC_SEQ_CST );
100+ }
101+
102+ T swap ( T new_val ) noexcept {
103+ return __atomic_exchange_n ( &value, new_val, __ATOMIC_SEQ_CST );
104+ }
105+
106+ bool compare ( T& expected, T desired ) const noexcept {
107+ return __atomic_compare_exchange_n ( &value, &expected, desired, false , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
108+ }
109+
110+ public:
111+
112+ template < typename U = T >
113+ typename type::enable_if< !type::is_pointer<U>::value, atomic_t & >::type
114+ operator &=( T value ) noexcept { _and (value); return *this ; }
115+
116+ template < typename U = T >
117+ typename type::enable_if< !type::is_pointer<U>::value, atomic_t & >::type
118+ operator |=( T value ) noexcept { _or (value); return *this ; }
119+
120+ template < typename U = T >
121+ typename type::enable_if< !type::is_pointer<U>::value, atomic_t & >::type
122+ operator ^=( T value ) noexcept { _xor (value); return *this ; }
123+
124+ template < typename U = T >
125+ typename type::enable_if< !type::is_pointer<U>::value, atomic_t & >::type
126+ operator -=( T value ) noexcept { sub (value); return *this ; }
127+
128+ template < typename U = T >
129+ typename type::enable_if< !type::is_pointer<U>::value, atomic_t & >::type
130+ operator +=( T value ) noexcept { add (value); return *this ; }
131+
132+ template < typename U = T >
133+ typename type::enable_if< !type::is_pointer<U>::value, T >::type
134+ operator --() /* -------------*/ noexcept { return sub (1 ) - 1 ; }
135+
136+ template < typename U = T >
137+ typename type::enable_if< !type::is_pointer<U>::value, T >::type
138+ operator ++() /* -------------*/ noexcept { return add (1 ) + 1 ; }
139+
140+ template < typename U = T >
141+ typename type::enable_if< !type::is_pointer<U>::value, T >::type
142+ operator --(int ) /* ----------*/ noexcept { return sub (1 ); }
143+
144+ template < typename U = T >
145+ typename type::enable_if< !type::is_pointer<U>::value, T >::type
146+ operator ++(int ) /* ----------*/ noexcept { return add (1 ); }
147+
148+ atomic_t & operator =( T value ) noexcept { set (value); return *this ; }
149+
150+ bool operator ==( T value ) const noexcept { return get () == value; }
151+ bool operator >=( T value ) const noexcept { return get () >= value; }
152+ bool operator <=( T value ) const noexcept { return get () <= value; }
153+ bool operator > ( T value ) const noexcept { return get () > value; }
154+ bool operator < ( T value ) const noexcept { return get () < value; }
155+ bool operator !=( T value ) const noexcept { return get () != value; }
156+
157+ explicit operator T () /* */ const noexcept { return get (); }
158+
159+ }; }
160+
161+ /* ────────────────────────────────────────────────────────────────────────────*/
162+
163+ #endif
164+
165+ /* ────────────────────────────────────────────────────────────────────────────*/
0 commit comments