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_add_explicit(volatile atomic<Integral>* obj, Integral op,
     15 //                               memory_order m);
     16 // template <class Integral>
     17 //     Integral
     18 //     atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
     19 //                               memory_order m);
     20 // template <class T>
     21 //     T*
     22 //     atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
     23 //                               memory_order m);
     24 // template <class T>
     25 //     T*
     26 //     atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
     27 
     28 #include <atomic>
     29 #include <type_traits>
     30 #include <cassert>
     31 
     32 template <class T>
     33 void
     34 test()
     35 {
     36     {
     37         typedef std::atomic<T> A;
     38         A t;
     39         std::atomic_init(&t, T(1));
     40         assert(std::atomic_fetch_add_explicit(&t, T(2),
     41                                             std::memory_order_seq_cst) == T(1));
     42         assert(t == T(3));
     43     }
     44     {
     45         typedef std::atomic<T> A;
     46         volatile A t;
     47         std::atomic_init(&t, T(1));
     48         assert(std::atomic_fetch_add_explicit(&t, T(2),
     49                                             std::memory_order_seq_cst) == T(1));
     50         assert(t == T(3));
     51     }
     52 }
     53 
     54 template <class T>
     55 void
     56 testp()
     57 {
     58     {
     59         typedef std::atomic<T> A;
     60         typedef typename std::remove_pointer<T>::type X;
     61         A t;
     62         std::atomic_init(&t, T(1*sizeof(X)));
     63         assert(std::atomic_fetch_add_explicit(&t, 2,
     64                                   std::memory_order_seq_cst) == T(1*sizeof(X)));
     65         assert(t == T(3*sizeof(X)));
     66     }
     67     {
     68         typedef std::atomic<T> A;
     69         typedef typename std::remove_pointer<T>::type X;
     70         volatile A t;
     71         std::atomic_init(&t, T(1*sizeof(X)));
     72         assert(std::atomic_fetch_add_explicit(&t, 2,
     73                                   std::memory_order_seq_cst) == T(1*sizeof(X)));
     74         assert(t == T(3*sizeof(X)));
     75     }
     76 }
     77 
     78 struct A
     79 {
     80     int i;
     81 
     82     explicit A(int d = 0) : i(d) {}
     83     A(const A& a) : i(a.i) {}
     84     A(const volatile A& a) : i(a.i) {}
     85 
     86     void operator=(const volatile A& a) volatile {i = a.i;}
     87 
     88     friend bool operator==(const A& x, const A& y)
     89         {return x.i == y.i;}
     90 };
     91 
     92 int main()
     93 {
     94     test<char>();
     95     test<signed char>();
     96     test<unsigned char>();
     97     test<short>();
     98     test<unsigned short>();
     99     test<int>();
    100     test<unsigned int>();
    101     test<long>();
    102     test<unsigned long>();
    103     test<long long>();
    104     test<unsigned long long>();
    105     test<wchar_t>();
    106 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
    107     test<char16_t>();
    108     test<char32_t>();
    109 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
    110     testp<int*>();
    111     testp<const int*>();
    112 }
    113