blob: 7ab047ffb49010ae17b7f73f16f56497e905e076 [file] [log] [blame]
/* 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;
}