Home | History | Annotate | Download | only in atomics.types.operations.req
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // <atomic>
     11 
     12 // template <class Integral>
     13 //     Integral
     14 //     atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
     15 //                               memory_order m);
     16 // template <class Integral>
     17 //     Integral
     18 //     atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
     19 //                               memory_order m);
     20 //
     21 // template <class T>
     22 //     T*
     23 //     atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
     24 //                               memory_order m);
     25 // template <class T>
     26 //     T*
     27 //     atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
     28 
     29 #include <atomic>
     30 #include <type_traits>
     31 #include <cassert>
     32 
     33 template <class T>
     34 void
     35 test()
     36 {
     37     {
     38         typedef std::atomic<T> A;
     39         A t;
     40         std::atomic_init(&t, T(3));
     41         assert(std::atomic_fetch_sub_explicit(&t, T(2),
     42                                             std::memory_order_seq_cst) == T(3));
     43         assert(t == T(1));
     44     }
     45     {
     46         typedef std::atomic<T> A;
     47         volatile A t;
     48         std::atomic_init(&t, T(3));
     49         assert(std::atomic_fetch_sub_explicit(&t, T(2),
     50                                             std::memory_order_seq_cst) == T(3));
     51         assert(t == T(1));
     52     }
     53 }
     54 
     55 template <class T>
     56 void
     57 testp()
     58 {
     59     {
     60         typedef std::atomic<T> A;
     61         typedef typename std::remove_pointer<T>::type X;
     62         A t;
     63         std::atomic_init(&t, T(3*sizeof(X)));
     64         assert(std::atomic_fetch_sub_explicit(&t, 2,
     65                                   std::memory_order_seq_cst) == T(3*sizeof(X)));
     66         assert(t == T(1*sizeof(X)));
     67     }
     68     {
     69         typedef std::atomic<T> A;
     70         typedef typename std::remove_pointer<T>::type X;
     71         volatile A t;
     72         std::atomic_init(&t, T(3*sizeof(X)));
     73         assert(std::atomic_fetch_sub_explicit(&t, 2,
     74                                   std::memory_order_seq_cst) == T(3*sizeof(X)));
     75         assert(t == T(1*sizeof(X)));
     76     }
     77 }
     78 
     79 struct A
     80 {
     81     int i;
     82 
     83     explicit A(int d = 0) : i(d) {}
     84     A(const A& a) : i(a.i) {}
     85     A(const volatile A& a) : i(a.i) {}
     86 
     87     void operator=(const volatile A& a) volatile {i = a.i;}
     88 
     89     friend bool operator==(const A& x, const A& y)
     90         {return x.i == y.i;}
     91 };
     92 
     93 int main()
     94 {
     95     test<char>();
     96     test<signed char>();
     97     test<unsigned char>();
     98     test<short>();
     99     test<unsigned short>();
    100     test<int>();
    101     test<unsigned int>();
    102     test<long>();
    103     test<unsigned long>();
    104     test<long long>();
    105     test<unsigned long long>();
    106     test<wchar_t>();
    107 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
    108     test<char16_t>();
    109     test<char32_t>();
    110 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
    111     testp<int*>();
    112     testp<const int*>();
    113 }
    114