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