// -*- C++ -*-
//===-- is_partitioned.pass.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include "support/pstl_test_config.h"

#include <execution>
#include <algorithm>

#include "support/utils.h"

using namespace TestUtils;

struct test_one_policy
{
    //dummy specialization by policy type, in case of broken configuration
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN

    template <typename Iterator1, typename Predicate>
    void
    operator()(pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
    {
    }
    template <typename Iterator1, typename Predicate>
    void
    operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
    {
    }
#endif

    template <typename ExecutionPolicy, typename Iterator1, typename Predicate>
    void
    operator()(ExecutionPolicy&& exec, Iterator1 begin1, Iterator1 end1, Predicate pred)
    {
        const bool expected = std::is_partitioned(begin1, end1, pred);
        const bool actual = std::is_partitioned(exec, begin1, end1, pred);
        EXPECT_TRUE(actual == expected, "wrong return result from is_partitioned");
    }
};

template <typename T, typename Predicate>
void
test(Predicate pred)
{

    const std::size_t max_n = 1000000;
    Sequence<T> in(max_n, [](std::size_t k) { return T(k); });

    for (std::size_t n1 = 0; n1 <= max_n; n1 = n1 <= 16 ? n1 + 1 : std::size_t(3.1415 * n1))
    {
        invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n1, pred);
        std::partition(in.begin(), in.begin() + n1, pred);
        invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, pred);
    }
}

template <typename T>
struct LocalWrapper
{
    explicit LocalWrapper(std::size_t k) : my_val(k) {}

  private:
    T my_val;
};

struct test_non_const
{
    template <typename Policy, typename Iterator>
    void
    operator()(Policy&& exec, Iterator iter)
    {
        auto is_even = [&](float64_t v) {
            uint32_t i = (uint32_t)v;
            return i % 2 == 0;
        };
        invoke_if(exec, [&]() { is_partitioned(exec, iter, iter, non_const(is_even)); });
    }
};

int
main()
{
    test<float64_t>([](const float64_t x) { return x < 0; });
    test<int32_t>([](const int32_t x) { return x > 1000; });
    test<uint16_t>([](const uint16_t x) { return x % 5 < 3; });
#if !_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN && !_PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN
    test<LocalWrapper<float64_t>>([](const LocalWrapper<float64_t>&) { return true; });
#endif

    test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());

    std::cout << done() << std::endl;
    return 0;
}
