diff --git a/examples/listdir.cc b/examples/listdir.cc index 5664582..a1fc6e6 100644 --- a/examples/listdir.cc +++ b/examples/listdir.cc @@ -7,7 +7,7 @@ using namespace ostd; void list_dirs(ConstCharRange path, int off = 0) { DirectoryStream ds{path}; /* iterate all items in directory */ - for (auto v: ds.iter()) { + for (auto v: iter(ds)) { if (v.type() != FileType::directory) { continue; } diff --git a/examples/range_pipe.cc b/examples/range_pipe.cc index 516de1e..c9e9e6d 100644 --- a/examples/range_pipe.cc +++ b/examples/range_pipe.cc @@ -69,9 +69,9 @@ int main() { srand(time(0)); Array arr; - generate(arr.iter(), []() { return rand() % 128; }); + generate(iter(arr), []() { return rand() % 128; }); - auto r = arr.iter() + auto r = iter(arr) | sort () | filter([](auto v) { return v >= 65 && v <= 90; }) | map ([](auto v) { return char(v); }); diff --git a/examples/stream2.cc b/examples/stream2.cc index 3592adc..3661b08 100644 --- a/examples/stream2.cc +++ b/examples/stream2.cc @@ -17,7 +17,7 @@ int main() { "This is after a few newlines. The file continues here.\n" "The file ends here.\n"; - copy(smpl.iter(), wtest.iter()); + copy(iter(smpl), wtest.iter()); wtest.close(); FileStream test{"test.txt"}; diff --git a/ostd/atomic.hh b/ostd/atomic.hh deleted file mode 100644 index 12c844a..0000000 --- a/ostd/atomic.hh +++ /dev/null @@ -1,991 +0,0 @@ -/* Atomics for OctaSTD. Supports GCC/Clang and possibly MSVC. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_ATOMIC_HH -#define OSTD_ATOMIC_HH - -#include -#include - -#include "ostd/types.hh" -#include "ostd/type_traits.hh" - -namespace ostd { - -enum class MemoryOrder { - relaxed = 0, - consume, - acquire, - release, - acq_rel, - seq_cst -}; - -namespace detail { - template - struct AtomicBase { - AtomicBase() {} - explicit AtomicBase(T v): p_value(v) {} - T p_value; - }; - - template - T atomic_create(); - - template - EnableIfvalue = atomic_create()), char> - test_atomic_assignable(int); - - template - int test_atomic_assignable(...); - - template - constexpr bool CanAtomicAssign = - (sizeof(test_atomic_assignable(1)) == sizeof(char)); - - template - static inline EnableIf< - CanAtomicAssign volatile *, T> - > atomic_init(AtomicBase volatile *a, T v) { - a->p_value = v; - } - - template - static inline EnableIf< - !CanAtomicAssign volatile *, T> && - CanAtomicAssign *, T> - > atomic_init(AtomicBase volatile *a, T v) { - char volatile *to = reinterpret_cast(&a->p_value); - char volatile *end = to + sizeof(T); - char *from = reinterpret_cast(&v); - while (to != end) { - *to++ =*from++; - } - } - - template - static inline void atomic_init(AtomicBase *a, T v) { - a->p_value = v; - } -} - - /* GCC, Clang support - * - * libc++ used for reference - */ - -#ifdef __GNUC__ - -static constexpr Size AtomicBoolLockFree = __GCC_ATOMIC_BOOL_LOCK_FREE; -static constexpr Size AtomicCharLockFree = __GCC_ATOMIC_CHAR_LOCK_FREE; -static constexpr Size AtomicChar16LockFree = __GCC_ATOMIC_CHAR16_T_LOCK_FREE; -static constexpr Size AtomicChar32LockFree = __GCC_ATOMIC_CHAR32_T_LOCK_FREE; -static constexpr Size AtomicWcharLockFree = __GCC_ATOMIC_WCHAR_T_LOCK_FREE; -static constexpr Size AtomicShortLockFree = __GCC_ATOMIC_SHORT_LOCK_FREE; -static constexpr Size AtomicIntLockFree = __GCC_ATOMIC_INT_LOCK_FREE; -static constexpr Size AtomicLongLockFree = __GCC_ATOMIC_LONG_LOCK_FREE; -static constexpr Size AtomicLlongLockFree = __GCC_ATOMIC_LLONG_LOCK_FREE; -static constexpr Size AtomicPointerLockFree = __GCC_ATOMIC_POINTER_LOCK_FREE; - -namespace detail { - static inline constexpr int to_gcc_order(MemoryOrder ord) { - return ( - ((ord == MemoryOrder::relaxed) ? __ATOMIC_RELAXED : - ((ord == MemoryOrder::acquire) ? __ATOMIC_ACQUIRE : - ((ord == MemoryOrder::release) ? __ATOMIC_RELEASE : - ((ord == MemoryOrder::seq_cst) ? __ATOMIC_SEQ_CST : - ((ord == MemoryOrder::acq_rel) ? __ATOMIC_ACQ_REL : - __ATOMIC_CONSUME))))) - ); - } - - static inline constexpr int to_gcc_failure_order(MemoryOrder ord) { - return ( - ((ord == MemoryOrder::relaxed) ? __ATOMIC_RELAXED : - ((ord == MemoryOrder::acquire) ? __ATOMIC_ACQUIRE : - ((ord == MemoryOrder::release) ? __ATOMIC_RELAXED : - ((ord == MemoryOrder::seq_cst) ? __ATOMIC_SEQ_CST : - ((ord == MemoryOrder::acq_rel) ? __ATOMIC_ACQUIRE : - __ATOMIC_CONSUME))))) - ); - } - - static inline void atomic_thread_fence(MemoryOrder ord) { - __atomic_thread_fence(to_gcc_order(ord)); - } - - static inline void atomic_signal_fence(MemoryOrder ord) { - __atomic_signal_fence(to_gcc_order(ord)); - } - - static inline bool atomic_is_lock_free(Size size) { - /* return __atomic_is_lock_free(size, 0); cannot be used on some platforms */ - return size <= sizeof(void *); - } - - template - static inline void atomic_store( - AtomicBase volatile *a, T v, MemoryOrder ord - ) { - __atomic_store(&a->p_value, &v, to_gcc_order(ord)); - } - - template - static inline void atomic_store(AtomicBase *a,T v, MemoryOrder ord) { - __atomic_store(&a->p_value, &v, to_gcc_order(ord)); - } - - template - static inline T atomic_load(AtomicBase volatile *a, MemoryOrder ord) { - T r; - __atomic_load(&a->p_value, &r, to_gcc_order(ord)); - return r; - } - - template - static inline T atomic_load(AtomicBase *a, MemoryOrder ord) { - T r; - __atomic_load(&a->p_value, &r, to_gcc_order(ord)); - return r; - } - - template - static inline T atomic_exchange(AtomicBase volatile *a, - T v, MemoryOrder ord) { - T r; - __atomic_exchange(&a->p_value, &v, &r, to_gcc_order(ord)); - return r; - } - - template - static inline T atomic_exchange(AtomicBase *a, T v, MemoryOrder ord) { - T r; - __atomic_exchange(&a->p_value, &v, &r, to_gcc_order(ord)); - return r; - } - - template - static inline bool atomic_compare_exchange_strong( - AtomicBase volatile *a, T *expected, T v, - MemoryOrder success, MemoryOrder failure - ) { - return __atomic_compare_exchange( - &a->p_value, expected, &v, false, - to_gcc_order(success), to_gcc_failure_order(failure) - ); - } - - template - static inline bool atomic_compare_exchange_strong( - AtomicBase *a, T *expected, T v, - MemoryOrder success, MemoryOrder failure - ) { - return __atomic_compare_exchange( - &a->p_value, expected, &v, false, - to_gcc_order(success), to_gcc_failure_order(failure) - ); - } - - template - static inline bool atomic_compare_exchange_weak( - AtomicBase volatile *a, T *expected, T v, - MemoryOrder success, MemoryOrder failure - ) { - return __atomic_compare_exchange( - &a->p_value, expected, &v, true, - to_gcc_order(success), to_gcc_failure_order(failure) - ); - } - - template - static inline bool atomic_compare_exchange_weak( - AtomicBase *a, T *expected, T v, - MemoryOrder success, MemoryOrder failure - ) { - return __atomic_compare_exchange( - &a->p_value, expected, &v, true, - to_gcc_order(success), to_gcc_failure_order(failure) - ); - } - - template - struct SkipAmt { static constexpr Size value = 1; }; - - template - struct SkipAmt { static constexpr Size value = sizeof(T); }; - - template - struct SkipAmt {}; - - template - struct SkipAmt {}; - - template - static inline T atomic_fetch_add( - AtomicBase volatile *a, U d, MemoryOrder ord - ) { - return __atomic_fetch_add( - &a->p_value, d * SkipAmt::value, to_gcc_order(ord) - ); - } - - template - static inline T atomic_fetch_add( - AtomicBase *a, U d, MemoryOrder ord - ) { - return __atomic_fetch_add( - &a->p_value, d * SkipAmt::value, to_gcc_order(ord) - ); - } - - template - static inline T atomic_fetch_sub( - AtomicBase volatile *a, U d, MemoryOrder ord - ) { - return __atomic_fetch_sub( - &a->p_value, d * SkipAmt::value, to_gcc_order(ord) - ); - } - - template - static inline T atomic_fetch_sub( - AtomicBase *a, U d, MemoryOrder ord - ) { - return __atomic_fetch_sub( - &a->p_value, d * SkipAmt::value, to_gcc_order(ord) - ); - } - - template - static inline T atomic_fetch_and( - AtomicBase volatile *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_and(&a->p_value, pattern, to_gcc_order(ord)); - } - - template - static inline T atomic_fetch_and( - AtomicBase *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_and(&a->p_value, pattern, to_gcc_order(ord)); - } - - template - static inline T atomic_fetch_or( - AtomicBase volatile *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_or(&a->p_value, pattern, to_gcc_order(ord)); - } - - template - static inline T atomic_fetch_or( - AtomicBase *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_or(&a->p_value, pattern, to_gcc_order(ord)); - } - - template - static inline T atomic_fetch_xor( - AtomicBase volatile *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_xor(&a->p_value, pattern, to_gcc_order(ord)); - } - - template - static inline T atomic_fetch_xor( - AtomicBase *a, T pattern, MemoryOrder ord - ) { - return __atomic_fetch_xor(&a->p_value, pattern, to_gcc_order(ord)); - } -} /* namespace detail */ -#else -# error Unsupported compiler -#endif - -template -inline T kill_dependency(T v) { - return v; -} - -namespace detail { - template && !IsSame> - struct Atomic { - mutable AtomicBase p_a; - - Atomic() = default; - - constexpr Atomic(T v): p_a(v) {} - - Atomic(Atomic const &) = delete; - - Atomic &operator=(Atomic const &) = delete; - Atomic &operator=(Atomic const &) volatile = delete; - - bool is_lock_free() const volatile { - return atomic_is_lock_free(sizeof(T)); - } - - bool is_lock_free() const { - return atomic_is_lock_free(sizeof(T)); - } - - void store(T v, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - atomic_store(&p_a, v, ord); - } - - void store(T v, MemoryOrder ord = MemoryOrder::seq_cst) { - atomic_store(&p_a, v, ord); - } - - T load(MemoryOrder ord = MemoryOrder::seq_cst) const volatile { - return atomic_load(&p_a, ord); - } - - T load(MemoryOrder ord = MemoryOrder::seq_cst) const { - return atomic_load(&p_a, ord); - } - - operator T() const volatile { return load(); } - operator T() const { return load(); } - - T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_exchange(&p_a, v, ord); - } - - T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_exchange(&p_a, v, ord); - } - - bool compare_exchange_weak( - T &e, T v, MemoryOrder s, MemoryOrder f - ) volatile { - return atomic_compare_exchange_weak(&p_a, &e, v, s, f); - } - - bool compare_exchange_weak(T &e, T v, MemoryOrder s, MemoryOrder f) { - return atomic_compare_exchange_weak(&p_a, &e, v, s, f); - } - - bool compare_exchange_strong( - T &e, T v, MemoryOrder s, MemoryOrder f - ) volatile { - return atomic_compare_exchange_strong(&p_a, &e, v, s, f); - } - - bool compare_exchange_strong(T &e, T v, MemoryOrder s, MemoryOrder f) { - return atomic_compare_exchange_strong(&p_a, &e, v, s, f); - } - - bool compare_exchange_weak( - T &e, T v, MemoryOrder ord = MemoryOrder::seq_cst - ) volatile { - return atomic_compare_exchange_weak(&p_a, &e, v, ord, ord); - } - - bool compare_exchange_weak( - T &e, T v, MemoryOrder ord = MemoryOrder::seq_cst - ) { - return atomic_compare_exchange_weak(&p_a, &e, v, ord, ord); - } - - bool compare_exchange_strong( - T &e, T v, MemoryOrder ord = MemoryOrder::seq_cst - ) volatile { - return atomic_compare_exchange_strong(&p_a, &e, v, ord, ord); - } - - bool compare_exchange_strong( - T &e, T v, MemoryOrder ord = MemoryOrder::seq_cst - ) { - return atomic_compare_exchange_strong(&p_a, &e, v, ord, ord); - } - }; - - template - struct Atomic: Atomic { - using Base = Atomic; - - Atomic() = default; - - constexpr Atomic(T v): Base(v) {} - - T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_fetch_add(&this->p_a, op, ord); - } - - T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_fetch_add(&this->p_a, op, ord); - } - - T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_fetch_sub(&this->p_a, op, ord); - } - - T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_fetch_sub(&this->p_a, op, ord); - } - - T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_fetch_and(&this->p_a, op, ord); - } - - T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_fetch_and(&this->p_a, op, ord); - } - - T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_fetch_or(&this->p_a, op, ord); - } - - T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_fetch_or(&this->p_a, op, ord); - } - - T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return atomic_fetch_xor(&this->p_a, op, ord); - } - - T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst) { - return atomic_fetch_xor(&this->p_a, op, ord); - } - - T operator++(int) volatile { return fetch_add(T(1)); } - T operator++(int) { return fetch_add(T(1)); } - T operator--(int) volatile { return fetch_sub(T(1)); } - T operator--(int) { return fetch_sub(T(1)); } - T operator++( ) volatile { return fetch_add(T(1)) + T(1); } - T operator++( ) { return fetch_add(T(1)) + T(1); } - T operator--( ) volatile { return fetch_sub(T(1)) - T(1); } - T operator--( ) { return fetch_sub(T(1)) - T(1); } - - T operator+=(T op) volatile { return fetch_add(op) + op; } - T operator+=(T op) { return fetch_add(op) + op; } - T operator-=(T op) volatile { return fetch_sub(op) - op; } - T operator-=(T op) { return fetch_sub(op) - op; } - T operator&=(T op) volatile { return fetch_and(op) & op; } - T operator&=(T op) { return fetch_and(op) & op; } - T operator|=(T op) volatile { return fetch_or (op) | op; } - T operator|=(T op) { return fetch_or (op) | op; } - T operator^=(T op) volatile { return fetch_xor(op) ^ op; } - T operator^=(T op) { return fetch_xor(op) ^ op; } - }; -} - -template -struct Atomic: detail::Atomic { - using Base = detail::Atomic; - - Atomic() = default; - - constexpr Atomic(T v): Base(v) {} - - T operator=(T v) volatile { - Base::store(v); return v; - } - - T operator=(T v) { - Base::store(v); return v; - } -}; - -template -struct Atomic: detail::Atomic { - using Base = detail::Atomic; - - Atomic() = default; - - constexpr Atomic(T *v): Base(v) {} - - T *operator=(T *v) volatile { - Base::store(v); return v; - } - - T *operator=(T *v) { - Base::store(v); return v; - } - - T *fetch_add(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) - volatile { - return detail::atomic_fetch_add(&this->p_a, op, ord); - } - - T *fetch_add(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) { - return detail::atomic_fetch_add(&this->p_a, op, ord); - } - - T *fetch_sub(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) - volatile { - return detail::atomic_fetch_sub(&this->p_a, op, ord); - } - - T *fetch_sub(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) { - return detail::atomic_fetch_sub(&this->p_a, op, ord); - } - - - T *operator++(int) volatile { return fetch_add(1); } - T *operator++(int) { return fetch_add(1); } - T *operator--(int) volatile { return fetch_sub(1); } - T *operator--(int) { return fetch_sub(1); } - T *operator++( ) volatile { return fetch_add(1) + 1; } - T *operator++( ) { return fetch_add(1) + 1; } - T *operator--( ) volatile { return fetch_sub(1) - 1; } - T *operator--( ) { return fetch_sub(1) - 1; } - - T *operator+=(Ptrdiff op) volatile { return fetch_add(op) + op; } - T *operator+=(Ptrdiff op) { return fetch_add(op) + op; } - T *operator-=(Ptrdiff op) volatile { return fetch_sub(op) - op; } - T *operator-=(Ptrdiff op) { return fetch_sub(op) - op; } -}; - -template -inline bool atomic_is_lock_free(Atomic const volatile *a) { - return a->is_lock_free(); -} - -template -inline bool atomic_is_lock_free(Atomic const *a) { - return a->is_lock_free(); -} - -template -inline void atomic_init(Atomic volatile *a, T v) { - detail::atomic_init(&a->p_a, v); -} - -template -inline void atomic_init(Atomic *a, T v) { - detail::atomic_init(&a->p_a, v); -} - -template -inline void atomic_store(Atomic volatile *a, T v) { - a->store(v); -} - -template -inline void atomic_store(Atomic *a, T v) { - a->store(v); -} - -template -inline void atomic_store_explicit(Atomic volatile *a, T v, MemoryOrder ord) { - a->store(v, ord); -} - -template -inline void atomic_store_explicit(Atomic *a, T v, MemoryOrder ord) { - a->store(v, ord); -} - -template -inline T atomic_load(Atomic const volatile *a) { - return a->load(); -} - -template -inline T atomic_load(Atomic const *a) { - return a->load(); -} - -template -inline T atomic_load_explicit(Atomic const volatile *a, MemoryOrder ord) { - return a->load(ord); -} - -template -inline T atomic_load_explicit(Atomic const *a, MemoryOrder ord) { - return a->load(ord); -} - -template -inline T atomic_exchange(Atomic volatile *a, T v) { - return a->exchange(v); -} - -template -inline T atomic_exchange(Atomic *a, T v) { - return a->exchange(v); -} - -template -inline T atomic_exchange_explicit(Atomic volatile *a, T v, MemoryOrder ord) { - return a->exchange(v, ord); -} - -template -inline T atomic_exchange_explicit(Atomic *a, T v, MemoryOrder ord) { - return a->exchange(v, ord); -} - -template -inline bool atomic_compare_exchange_weak(Atomic volatile *a, T *e, T v) { - return a->compare_exchange_weak(*e, v); -} - -template -inline bool atomic_compare_exchange_weak(Atomic *a, T *e, T v) { - return a->compare_exchange_weak(*e, v); -} - -template -inline bool atomic_compare_exchange_strong(Atomic volatile *a, T *e, T v) { - return a->compare_exchange_strong(*e, v); -} - -template -inline bool atomic_compare_exchange_strong(Atomic *a, T *e, T v) { - return a->compare_exchange_strong(*e, v); -} - -template -inline bool atomic_compare_exchange_weak_explicit( - Atomic volatile *a, T *e, T v, MemoryOrder s, MemoryOrder f -) { - return a->compare_exchange_weak(*e, v, s, f); -} - -template -inline bool atomic_compare_exchange_weak_explicit( - Atomic *a, T *e, T v, MemoryOrder s, MemoryOrder f -) { - return a->compare_exchange_weak(*e, v, s, f); -} - -template -inline bool atomic_compare_exchange_strong_explicit( - Atomic volatile *a, T *e, T v, MemoryOrder s, MemoryOrder f -) { - return a->compare_exchange_strong(*e, v, s, f); -} - -template -inline bool atomic_compare_exchange_strong_explicit( - Atomic *a, T *e, T v, MemoryOrder s, MemoryOrder f -) { - return a->compare_exchange_strong(*e, v, s, f); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_add( - Atomic volatile *a, T op -) { - return a->fetch_add(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_add( - Atomic *a, T op -) { - return a->fetch_add(op); -} - -template -inline T *atomic_fetch_add(Atomic volatile *a, Ptrdiff op) { - return a->fetch_add(op); -} - -template -inline T *atomic_fetch_add(Atomic *a, Ptrdiff op) { - return a->fetch_add(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_add_explicit( - Atomic volatile *a, T op, MemoryOrder ord -) { - return a->fetch_add(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_add_explicit( - Atomic *a, T op, MemoryOrder ord -) { - return a->fetch_add(op, ord); -} - -template -inline T *atomic_fetch_add_explicit( - Atomic volatile *a, Ptrdiff op, MemoryOrder ord -) { - return a->fetch_add(op, ord); -} - -template -inline T *atomic_fetch_add_explicit( - Atomic *a, Ptrdiff op, MemoryOrder ord -) { - return a->fetch_add(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_sub( - Atomic volatile *a, T op -) { - return a->fetch_sub(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_sub( - Atomic *a, T op -) { - return a->fetch_sub(op); -} - -template -inline T *atomic_fetch_sub(Atomic volatile *a, Ptrdiff op) { - return a->fetch_sub(op); -} - -template -inline T *atomic_fetch_sub(Atomic *a, Ptrdiff op) { - return a->fetch_sub(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_sub_explicit( - Atomic volatile *a, T op, MemoryOrder ord -) { - return a->fetch_sub(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_sub_explicit( - Atomic *a, T op, MemoryOrder ord -) { - return a->fetch_sub(op, ord); -} - -template -inline T *atomic_fetch_sub_explicit( - Atomic volatile *a, Ptrdiff op, MemoryOrder ord -) { - return a->fetch_sub(op, ord); -} - -template -inline T *atomic_fetch_sub_explicit( - Atomic *a, Ptrdiff op, MemoryOrder ord -) { - return a->fetch_sub(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_and( - Atomic volatile *a, T op -) { - return a->fetch_and(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_and( - Atomic *a, T op -) { - return a->fetch_and(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_and_explicit( - Atomic volatile *a, T op, MemoryOrder ord -) { - return a->fetch_and(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_and_explicit( - Atomic *a, T op, MemoryOrder ord -) { - return a->fetch_and(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_or( - Atomic volatile *a, T op -) { - return a->fetch_or(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_or( - Atomic *a, T op -) { - return a->fetch_or(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_or_explicit( - Atomic volatile *a, T op, MemoryOrder ord -) { - return a->fetch_or(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_or_explicit( - Atomic *a, T op, MemoryOrder ord -) { - return a->fetch_or(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_xor( - Atomic volatile *a, T op -) { - return a->fetch_xor(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_xor( - Atomic *a, T op -) { - return a->fetch_xor(op); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_xor_explicit( - Atomic volatile *a, T op, MemoryOrder ord -) { - return a->fetch_xor(op, ord); -} - -template -inline EnableIf && !IsSame, T> atomic_fetch_xor_explicit( - Atomic *a, T op, MemoryOrder ord -) { - return a->fetch_xor(op, ord); -} - -struct AtomicFlag { - detail::AtomicBase p_a; - - AtomicFlag() = default; - - AtomicFlag(bool b): p_a(b) {} - - AtomicFlag(AtomicFlag const &) = delete; - - AtomicFlag &operator=(AtomicFlag const &) = delete; - AtomicFlag &operator=(AtomicFlag const &) volatile = delete; - - bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) volatile { - return detail::atomic_exchange(&p_a, true, ord); - } - - bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) { - return detail::atomic_exchange(&p_a, true, ord); - } - - void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile { - detail::atomic_store(&p_a, false, ord); - } - - void clear(MemoryOrder ord = MemoryOrder::seq_cst) { - detail::atomic_store(&p_a, false, ord); - } -}; - -inline bool atomic_flag_test_and_set(AtomicFlag volatile *a) { - return a->test_and_set(); -} - -inline bool atomic_flag_test_and_set(AtomicFlag *a) { - return a->test_and_set(); -} - -inline bool atomic_flag_test_and_set_explicit( - AtomicFlag volatile *a, MemoryOrder ord -) { - return a->test_and_set(ord); -} - -inline bool atomic_flag_test_and_set_explicit(AtomicFlag *a, MemoryOrder ord) { - return a->test_and_set(ord); -} - -inline void atomic_flag_clear(AtomicFlag volatile *a) { - a->clear(); -} - -inline void atomic_flag_clear(AtomicFlag *a) { - a->clear(); -} - -inline void atomic_flag_clear_explicit(AtomicFlag volatile *a, MemoryOrder ord) { - a->clear(ord); -} - -inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord) { - a->clear(ord); -} - -inline void atomic_thread_fence(MemoryOrder ord) { - detail::atomic_thread_fence(ord); -} - -inline void atomic_signal_fence(MemoryOrder ord) { - detail::atomic_signal_fence(ord); -} - -using AtomicBool = Atomic; -using AtomicChar = Atomic; -using AtomicShort = Atomic; -using AtomicInt = Atomic; -using AtomicLong = Atomic; -using AtomicSbyte = Atomic; -using AtomicByte = Atomic; -using AtomicUshort = Atomic; -using AtomicUint = Atomic; -using AtomicUlong = Atomic; -using AtomicLlong = Atomic; -using AtomicUllong = Atomic; - -using AtomicChar16 = Atomic; -using AtomicChar32 = Atomic; -using AtomicWchar = Atomic; - -using AtomicPtrdiff = Atomic; -using AtomicSize = Atomic; - -using AtomicIntmax = Atomic; -using AtomicUintmax = Atomic; - -using AtomicIntptr = Atomic; -using AtomicUintptr = Atomic; - -using AtomicInt8 = Atomic; -using AtomicInt16 = Atomic; -using AtomicInt32 = Atomic; -using AtomicInt64 = Atomic; - -using AtomicUint8 = Atomic; -using AtomicUint16 = Atomic; -using AtomicUint32 = Atomic; -using AtomicUint64 = Atomic; - -using AtomicIntLeast8 = Atomic; -using AtomicIntLeast16 = Atomic; -using AtomicIntLeast32 = Atomic; -using AtomicIntLeast64 = Atomic; - -using AtomicUintLeast8 = Atomic; -using AtomicUintLeast16 = Atomic; -using AtomicUintLeast32 = Atomic; -using AtomicUintLeast64 = Atomic; - -using AtomicIntFast8 = Atomic; -using AtomicIntFast16 = Atomic; -using AtomicIntFast32 = Atomic; -using AtomicIntFast64 = Atomic; - -using AtomicUintFast8 = Atomic; -using AtomicUintFast16 = Atomic; -using AtomicUintFast32 = Atomic; -using AtomicUintFast64 = Atomic; - -#define ATOMIC_FLAG_INIT {false} -#define ATOMIC_VAR_INIT(v) {v} - -} - -#endif diff --git a/ostd/condition.hh b/ostd/condition.hh deleted file mode 100644 index 059bc6c..0000000 --- a/ostd/condition.hh +++ /dev/null @@ -1,11 +0,0 @@ -/* Condition variables. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_CONDITION_HH -#define OSTD_CONDITION_HH - -#include "ostd/internal/mutex.hh" - -#endif diff --git a/ostd/internal/mutex.hh b/ostd/internal/mutex.hh deleted file mode 100644 index 2dab1a4..0000000 --- a/ostd/internal/mutex.hh +++ /dev/null @@ -1,200 +0,0 @@ -/* Locking related core internals. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_INTERNAL_MUTEX_HH -#define OSTD_INTERNAL_MUTEX_HH - -#include -#include - -#include "ostd/utility.hh" - -namespace ostd { - -struct Mutex { - using NativeHandle = pthread_mutex_t *; - - constexpr Mutex(): p_mtx(PTHREAD_MUTEX_INITIALIZER) {} - - ~Mutex() { - pthread_mutex_destroy(&p_mtx); - } - - Mutex(const Mutex &) = delete; - Mutex &operator=(const Mutex &) = delete; - - bool lock() { - return !pthread_mutex_lock(&p_mtx); - } - - int try_lock() { - /* TODO handle return value correctly */ - return pthread_mutex_trylock(&p_mtx); - } - - bool unlock() { - return !pthread_mutex_unlock(&p_mtx); - } - - NativeHandle native_handle() { return &p_mtx; } - -private: - pthread_mutex_t p_mtx; -}; - -struct DeferLock {}; -struct TryToLock {}; -struct AdoptLock {}; - -constexpr DeferLock defer_lock {}; -constexpr TryToLock try_to_lock {}; -constexpr AdoptLock adopt_lock {}; - -template -struct LockGuard { - using MutexType = T; - - explicit LockGuard(MutexType &m): p_mtx(m) { m.lock(); } - LockGuard(MutexType &m, AdoptLock): p_mtx(m) {} - ~LockGuard() { p_mtx.unlock(); } - - LockGuard(const LockGuard &) = delete; - LockGuard &operator=(const LockGuard &) = delete; - -private: - MutexType &p_mtx; -}; - -template -struct UniqueLock { - using MutexType = T; - - UniqueLock(): p_mtx(nullptr), p_owns(false) {} - - explicit UniqueLock(MutexType &m): p_mtx(&m), p_owns(true) { - m.lock(); - } - - UniqueLock(MutexType &m, DeferLock): p_mtx(&m), p_owns(false) {} - - UniqueLock(MutexType &m, TryToLock): p_mtx(&m) { - int ret = m.try_lock(); - if (ret) { - p_mtx = nullptr; - p_owns = false; - return; - } - p_owns = (ret == 0); - } - - UniqueLock(MutexType &m, AdoptLock): p_mtx(&m), p_owns(true) {} - - ~UniqueLock() { - if (p_owns) { - p_mtx->unlock(); - } - } - - UniqueLock(const UniqueLock &) = delete; - UniqueLock &operator=(const UniqueLock &) = delete; - - UniqueLock(UniqueLock &&u): p_mtx(u.p_mtx), p_owns(u.p_owns) { - u.p_mtx = nullptr; - u.p_owns = false; - } - - UniqueLock &operator=(UniqueLock &&u) { - if (p_owns) { - p_mtx->unlock(); - } - p_mtx = u.p_mtx; - p_owns = u.p_owns; - u.p_mtx = nullptr; - u.p_owns = false; - return *this; - } - - bool lock() { - if (!p_mtx || p_owns) { - return false; - } - return (p_owns = p_mtx->lock()); - } - - int try_lock() { - if (!p_mtx || p_owns) { - return 1; - } - int ret = p_mtx->try_lock(); - p_owns = (ret == 0); - return ret; - } - - bool unlock() { - if (!p_mtx || !p_owns) { - return false; - } - bool ret = p_mtx->unlock(); - p_owns = !ret; - return ret; - } - - void swap(UniqueLock &u) { - detail::swap_adl(p_mtx, u.p_mtx); - detail::swap_adl(p_owns, u.p_owns); - } - - MutexType *release() { - MutexType *ret = p_mtx; - p_mtx = nullptr; - p_owns = false; - return ret; - } - - bool owns_lock() const { return p_owns; } - explicit operator bool() const { return p_owns; } - MutexType *mutex() const { return p_mtx; } - -private: - MutexType *p_mtx; - bool p_owns; -}; - -struct Condition { - using NativeHandle = pthread_cond_t *; - - constexpr Condition(): p_cnd(PTHREAD_COND_INITIALIZER) {} - - Condition(const Condition &) = delete; - Condition &operator=(const Condition &) = delete; - - ~Condition() { - pthread_cond_destroy(&p_cnd); - } - - bool signal() { - return !pthread_cond_signal(&p_cnd); - } - - bool broadcast() { - return !pthread_cond_broadcast(&p_cnd); - } - - bool wait(UniqueLock &l) { - if (!l.owns_lock()) { - return false; - } - return !pthread_cond_wait(&p_cnd, l.mutex()->native_handle()); - } - - NativeHandle native_handle() { return &p_cnd; } - -private: - pthread_cond_t p_cnd; -}; - -} /* namespace ostd */ - -#endif diff --git a/ostd/mutex.hh b/ostd/mutex.hh deleted file mode 100644 index 2d38d55..0000000 --- a/ostd/mutex.hh +++ /dev/null @@ -1,11 +0,0 @@ -/* Locking primitives. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_MUTEX_HH -#define OSTD_MUTEX_HH - -#include "ostd/internal/mutex.hh" - -#endif diff --git a/ostd/thread.hh b/ostd/thread.hh deleted file mode 100644 index 6d1f81c..0000000 --- a/ostd/thread.hh +++ /dev/null @@ -1,199 +0,0 @@ -/* Thread support library. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_THREAD_HH -#define OSTD_THREAD_HH - -#include -#include - -#include "ostd/platform.hh" -#include "ostd/internal/win32.hh" - -#ifdef OSTD_PLATFORM_POSIX -#include -#endif - -#include "ostd/memory.hh" -#include "ostd/type_traits.hh" -#include "ostd/tuple.hh" - -namespace ostd { - -struct Thread; - -namespace detail { - struct ThreadId; -} - -namespace this_thread { - inline ostd::detail::ThreadId get_id(); -} - -namespace detail { - struct ThreadId { - ThreadId(): p_thread(0) {} - - friend bool operator==(ThreadId a, ThreadId b) { - return a.p_thread == b.p_thread; - } - - friend bool operator!=(ThreadId a, ThreadId b) { - return !(a == b); - } - - friend bool operator<(ThreadId a, ThreadId b) { - return a.p_thread < b.p_thread; - } - - friend bool operator<=(ThreadId a, ThreadId b) { - return !(b < a); - } - - friend bool operator>(ThreadId a, ThreadId b) { - return b < a; - } - - friend bool operator>=(ThreadId a, ThreadId b) { - return !(a < b); - } - private: - ThreadId(pthread_t t): p_thread(t) {} - - friend struct ostd::Thread; - friend ThreadId ostd::this_thread::get_id(); - - pthread_t p_thread; - }; -} - -namespace this_thread { - inline ostd::detail::ThreadId get_id() { - return pthread_self(); - } - - inline void yield() { - sched_yield(); - } - - inline void exit() { - pthread_exit(nullptr); - } -} - -namespace detail { - template - inline Decay decay_copy(T &&v) { - return forward(v); - } - - template - inline void thread_exec(Tuple &tup, detail::TupleIndices) { - ostd::get<0>(tup)(ostd::move(ostd::get(tup))...); - } - - template - inline void *thread_proxy(void *ptr) { - Box fptr(static_cast(ptr)); - using Index = detail::MakeTupleIndices, 1>; - detail::thread_exec(*fptr, Index()); - return nullptr; - } -} - -struct Thread { - using NativeHandle = pthread_t; - - Thread(): p_thread(0) {} - Thread(Thread &&o): p_thread(o.p_thread) { o.p_thread = 0; } - - template< - typename F, typename ...A, typename = EnableIf, Thread>> - > - Thread(F &&func, A &&...args) { - using FuncT = Tuple, Decay...>; - Box p(new FuncT( - detail::decay_copy(forward(func)), - detail::decay_copy(forward(args))... - )); - int res = pthread_create( - &p_thread, 0, &detail::thread_proxy, p.get() - ); - if (!res) { - p.release(); - } else { - p_thread = 0; - } - } - - Thread &operator=(Thread &&other) { - if (joinable()) { - abort(); - } - p_thread = other.p_thread; - other.p_thread = 0; - return *this; - } - - ~Thread() { - if (joinable()) { - abort(); - } - } - - explicit operator bool() const { return joinable(); } - bool joinable() const { return p_thread != 0; } - - NativeHandle native_handle() { return p_thread; } - - detail::ThreadId get_id() { - return p_thread; - } - - bool join() { - auto ret = pthread_join(p_thread, nullptr); - p_thread = 0; - return !ret; - } - - bool detach() { - bool ret = false; - if (p_thread) { - ret = !pthread_detach(p_thread); - } - p_thread = 0; - return ret; - } - - void swap(Thread &other) { - auto cur = p_thread; - p_thread = other.p_thread; - other.p_thread = cur; - } - - static ostd::uint hardware_concurrency() { - static ostd::uint count = 0; - if (count <= 0) { -#ifdef OSTD_PLATFORM_WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - count = info.dwNumberOfProcessors; -#elif defined(_SC_NPROCESSORS_ONLN) - count = ostd::uint(sysconf(_SC_NPROCESSORS_ONLN)); -#endif - if (count <= 0) { - count = 1; - } - } - return count; - } - -private: - pthread_t p_thread; -}; - -} /* namespace ostd */ - -#endif diff --git a/test_runner.cc b/test_runner.cc index ac6f87d..d18cd57 100644 --- a/test_runner.cc +++ b/test_runner.cc @@ -49,7 +49,7 @@ int main() { }; DirectoryStream ds(testdir); - for (auto v: ds.iter()) { + for (auto v: iter(ds)) { if ((v.type() != FileType::regular) || (v.extension() != srcext)) continue;