| /* Container adaptors in target region. |
| Does not test comparison operators other than equality to allow these tests |
| to be generalized to arbitrary input data. */ |
| |
| #include <algorithm> |
| #include <cstdio> |
| #include <deque> |
| #include <queue> |
| #include <stack> |
| #include <vector> |
| |
| #include "target-flex-common.h" |
| |
| template<typename T, std::size_t Size> |
| bool test_stack(T (&arr)[Size]) |
| { |
| bool ok; |
| #pragma omp target map(from: ok) map(to: arr[:Size]) |
| { |
| bool inner_ok = true; |
| const std::size_t half_size = Size / 2; |
| const T first_element = arr[0]; |
| const T middle_element = arr[half_size - 1]; |
| const T last_element = arr[Size - 1]; |
| typedef std::stack<T, std::vector<T> > stack_type; |
| stack_type stack; |
| VERIFY (stack.empty()); |
| VERIFY (stack.size() == 0); |
| { |
| /* Do half with push. */ |
| std::size_t idx = 0; |
| for (; idx < half_size; ++idx) |
| { |
| stack.push(arr[idx]); |
| VERIFY (stack.top() == arr[idx]); |
| } |
| VERIFY (stack.size() == half_size); |
| VERIFY (static_cast<const stack_type&>(stack).size() == half_size); |
| for (; idx < Size; ++idx) |
| { |
| #if __cplusplus >= 201103L |
| /* Do the rest with emplace if C++11 or higher. */ |
| stack.emplace(arr[idx]); |
| #else |
| /* Otherwise just use push again. */ |
| stack.push(arr[idx]); |
| #endif |
| VERIFY (stack.top() == arr[idx]); |
| } |
| VERIFY (stack.size() == Size); |
| VERIFY (static_cast<const stack_type&>(stack).size() == Size); |
| |
| const stack_type stack_orig = stack_type(std::vector<T>(arr, arr + Size)); |
| VERIFY (stack == stack_orig); |
| /* References are contained in their own scope so we don't accidently |
| add tests referencing them after they have been invalidated. */ |
| { |
| const T& const_top = static_cast<const stack_type&>(stack).top(); |
| VERIFY (const_top == last_element); |
| T& mutable_top = stack.top(); |
| mutable_top = first_element; |
| VERIFY (const_top == first_element); |
| } |
| /* Will only compare inequal if the first and last elements are different. */ |
| VERIFY (first_element != last_element || stack != stack_orig); |
| for (std::size_t count = Size - half_size; count != 0; --count) |
| stack.pop(); |
| VERIFY (stack.top() == middle_element); |
| const stack_type stack_half_orig = stack_type(std::vector<T>(arr, arr + half_size)); |
| VERIFY (stack == stack_half_orig); |
| } |
| end: |
| ok = inner_ok; |
| } |
| return ok; |
| } |
| |
| template<typename T, std::size_t Size> |
| bool test_queue(T (&arr)[Size]) |
| { |
| bool ok; |
| #pragma omp target map(from: ok) map(to: arr[:Size]) |
| { |
| bool inner_ok = true; |
| const std::size_t half_size = Size / 2; |
| const T first_element = arr[0]; |
| const T last_element = arr[Size - 1]; |
| typedef std::queue<T, std::deque<T> > queue_type; |
| queue_type queue; |
| VERIFY (queue.empty()); |
| VERIFY (queue.size() == 0); |
| { |
| /* Do half with push. */ |
| std::size_t idx = 0; |
| for (; idx < half_size; ++idx) |
| { |
| queue.push(arr[idx]); |
| VERIFY (queue.back() == arr[idx]); |
| VERIFY (queue.front() == first_element); |
| } |
| VERIFY (queue.size() == half_size); |
| VERIFY (static_cast<const queue_type&>(queue).size() == half_size); |
| for (; idx < Size; ++idx) |
| { |
| #if __cplusplus >= 201103L |
| /* Do the rest with emplace if C++11 or higher. */ |
| queue.emplace(arr[idx]); |
| #else |
| /* Otherwise just use push again. */ |
| queue.push(arr[idx]); |
| #endif |
| VERIFY (queue.back() == arr[idx]); |
| } |
| VERIFY (queue.size() == Size); |
| VERIFY (static_cast<const queue_type&>(queue).size() == Size); |
| |
| const queue_type queue_orig = queue_type(std::deque<T>(arr, arr + Size)); |
| VERIFY (queue == queue_orig); |
| |
| /* References are contained in their own scope so we don't accidently |
| add tests referencing them after they have been invalidated. */ |
| { |
| const T& const_front = static_cast<const queue_type&>(queue).front(); |
| VERIFY (const_front == first_element); |
| T& mutable_front = queue.front(); |
| |
| const T& const_back = static_cast<const queue_type&>(queue).back(); |
| VERIFY (const_back == last_element); |
| T& mutable_back = queue.back(); |
| { |
| using std::swap; |
| swap(mutable_front, mutable_back); |
| } |
| VERIFY (const_front == last_element); |
| VERIFY (const_back == first_element); |
| /* Will only compare inequal if the first and last elements are different. */ |
| VERIFY (first_element != last_element || queue != queue_orig); |
| /* Return the last element to normal for the next comparison. */ |
| mutable_back = last_element; |
| } |
| |
| const T middle_element = arr[half_size]; |
| for (std::size_t count = Size - half_size; count != 0; --count) |
| queue.pop(); |
| VERIFY (queue.front() == middle_element); |
| const queue_type queue_upper_half = queue_type(std::deque<T>(arr + half_size, arr + Size)); |
| VERIFY (queue == queue_upper_half); |
| } |
| end: |
| ok = inner_ok; |
| } |
| return ok; |
| } |
| |
| template<typename T, std::size_t Size> |
| bool test_priority_queue(T (&arr)[Size], const T min_value, const T max_value) |
| { |
| bool ok; |
| #pragma omp target map(from: ok) map(to: arr[:Size]) |
| { |
| bool inner_ok = true; |
| typedef std::priority_queue<T, std::vector<T> > priority_queue_type; |
| { |
| priority_queue_type pqueue; |
| VERIFY (pqueue.empty()); |
| VERIFY (pqueue.size() == 0); |
| } |
| { |
| priority_queue_type pqueue(arr, arr + Size); |
| VERIFY (!pqueue.empty()); |
| VERIFY (pqueue.size() == Size); |
| VERIFY (static_cast<const priority_queue_type&>(pqueue).size() == Size); |
| |
| const T old_max = pqueue.top(); |
| |
| #if __cplusplus >= 201103L |
| pqueue.emplace(max_value); |
| #else |
| pqueue.push(max_value); |
| #endif |
| VERIFY (pqueue.top() == max_value); |
| pqueue.pop(); |
| VERIFY (pqueue.top() == old_max); |
| pqueue.push(min_value); |
| VERIFY (pqueue.top() == old_max); |
| pqueue.push(max_value); |
| VERIFY (pqueue.top() == max_value); |
| pqueue.pop(); |
| VERIFY (pqueue.top() == old_max); |
| VERIFY (pqueue.size() == Size + 1); |
| |
| for (std::size_t count = Size; count != 0; --count) |
| pqueue.pop(); |
| VERIFY (pqueue.size() == 1); |
| VERIFY (pqueue.top() == min_value); |
| } |
| end: |
| ok = inner_ok; |
| } |
| return ok; |
| } |
| |
| int main() |
| { |
| int arr[10] = {0,1,2,3,4,5,6,7,8,9}; |
| |
| return test_stack(arr) |
| && test_queue(arr) |
| && test_priority_queue(arr, 0, 1000) ? 0 : 1; |
| } |