//===----------------------------------------------------------------------===//
//
// 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++98, c++03

// <experimental/memory_resource>

// template <class T> class polymorphic_allocator

// template <class U, class ...Args>
// void polymorphic_allocator<T>::construct(U *, Args &&...)

#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
#include <cstdlib>

#include "test_macros.h"
#include "test_memory_resource.h"
#include "uses_alloc_types.h"
#include "controlled_allocators.h"
#include "test_allocator.h"

namespace ex = std::experimental::pmr;

template <class T>
struct PMATest {
    TestResource R;
    ex::polymorphic_allocator<T> A;
    T* ptr;
    bool constructed;

    PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {}

    template <class ...Args>
    void construct(Args&&... args) {
        A.construct(ptr, std::forward<Args>(args)...);
        constructed = true;
    }

    ~PMATest() {
        if (constructed) A.destroy(ptr);
        A.deallocate(ptr, 1);
    }
};

template <class T, class ...Args>
bool doTest(UsesAllocatorType UAExpect, Args&&... args)
{
    PMATest<T> TH;
    // UNDER TEST //
    TH.construct(std::forward<Args>(args)...);
    return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R);
    // ------- //
}


template <class T, class ...Args>
bool doTestUsesAllocV0(Args&&... args)
{
    PMATest<T> TH;
    // UNDER TEST //
    TH.construct(std::forward<Args>(args)...);
    return checkConstruct<Args&&...>(*TH.ptr, UA_None);
    // -------- //
}


template <class T, class EAlloc, class ...Args>
bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args)
{
    PMATest<T> TH;
    // UNDER TEST //
    TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...);
    return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc);
    // -------- //
}

template <class T, class EAlloc, class ...Args>
bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args)
{
    PMATest<T> TH;
    // UNDER TEST //
    TH.construct(std::forward<Args>(args)..., ealloc);
    return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc);
    // -------- //
}

template <class Alloc, class ...Args>
void test_pmr_uses_alloc(Args&&... args)
{
    TestResource R(12435);
    ex::memory_resource* M = &R;
    {
        // NotUsesAllocator provides valid signatures for each uses-allocator
        // construction but does not supply the required allocator_type typedef.
        // Test that we can call these constructors manually without
        // polymorphic_allocator interfering.
        using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...)));
        assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...)));
    }
    {
        // Test T(std::allocator_arg_t, Alloc const&, Args...) construction
        using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
    }
    {
        // Test T(Args..., Alloc const&) construction
        using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...)));
    }
    {
        // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
        // is preferred when T(Args..., Alloc const&) is also available.
        using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
    }
}

template <class Alloc, class ...Args>
void test_pmr_not_uses_alloc(Args&&... args)
{
    TestResource R(12435);
    ex::memory_resource* M = &R;
    {
        // NotUsesAllocator provides valid signatures for each uses-allocator
        // construction but does not supply the required allocator_type typedef.
        // Test that we can call these constructors manually without
        // polymorphic_allocator interfering.
        using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...)));
        assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...)));
    }
    {
        // Test T(std::allocator_arg_t, Alloc const&, Args...) construction
        using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_None, std::forward<Args>(args)...)));
    }
    {
        // Test T(Args..., Alloc const&) construction
        using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_None, std::forward<Args>(args)...)));
    }
    {
        // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
        // is preferred when T(Args..., Alloc const&) is also available.
        using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
        assert((doTest<T>(UA_None, std::forward<Args>(args)...)));
    }
}

// Test that polymorphic_allocator does not prevent us from manually
// doing non-pmr uses-allocator construction.
template <class Alloc, class AllocObj, class ...Args>
void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args)
{
    {
        using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
        assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
    }
    {
        using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
    }
    {
        using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
    }
    {
        using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
        assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
        assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
        assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
    }
}

int main(int, char**)
{
    using ET = std::experimental::erased_type;
    using PMR = ex::memory_resource*;
    using PMA = ex::polymorphic_allocator<void>;
    using STDA = std::allocator<char>;
    using TESTA = test_allocator<char>;

    int value = 42;
    const int cvalue = 43;
    {
        test_pmr_uses_alloc<ET>();
        test_pmr_not_uses_alloc<PMR>();
        test_pmr_uses_alloc<PMA>();
        test_pmr_uses_alloc<ET>(value);
        test_pmr_not_uses_alloc<PMR>(value);
        test_pmr_uses_alloc<PMA>(value);
        test_pmr_uses_alloc<ET>(cvalue);
        test_pmr_not_uses_alloc<PMR>(cvalue);
        test_pmr_uses_alloc<PMA>(cvalue);
        test_pmr_uses_alloc<ET>(cvalue, std::move(value));
        test_pmr_not_uses_alloc<PMR>(cvalue, std::move(value));
        test_pmr_uses_alloc<PMA>(cvalue, std::move(value));
    }
    {
        STDA std_alloc;
        TESTA test_alloc(42);
        test_non_pmr_uses_alloc<STDA>(std_alloc);
        test_non_pmr_uses_alloc<TESTA>(test_alloc);
        test_non_pmr_uses_alloc<STDA>(std_alloc, value);
        test_non_pmr_uses_alloc<TESTA>(test_alloc, value);
        test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue);
        test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue);
        test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value));
        test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value));
    }

  return 0;
}
