//===----------------------------------------------------------------------===//
//
// 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

// <scoped_allocator>

// template <class OtherAlloc, class ...InnerAlloc>
//   class scoped_allocator_adaptor

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

#include <scoped_allocator>
#include <type_traits>
#include <utility>
#include <tuple>
#include <cassert>
#include <cstdlib>
#include "uses_alloc_types.hpp"
#include "controlled_allocators.hpp"

#include "test_macros.h"

// - If uses_allocator_v<T, inner_allocator_type> is false and
//   is_constructible_v<T, Args...> is true, calls
//   OUTERMOST_ALLOC_TRAITS(*this)::construct(
//      OUTERMOST (*this), p, std::forward<Args>(args)...).
void test_bullet_one() {
    using VoidAlloc2 = CountingAllocator<void, 2>;

    AllocController POuter;
    AllocController PInner;
    {
        using T = NotUsesAllocator<VoidAlloc2, 3>;
        using Outer = CountingAllocator<T, 1>;
        using Inner = CountingAllocator<T, 2>;
        using SA = std::scoped_allocator_adaptor<Outer, Inner>;
        static_assert(!std::uses_allocator<T, Outer>::value, "");
        static_assert(!std::uses_allocator<T, Inner>::value, "");
        T* ptr = (T*)::operator new(sizeof(T));
        Outer O(POuter);
        Inner I(PInner);
        SA A(O, I);
        int x = 42;
        int const& cx = x;
        A.construct(ptr, x, cx, std::move(x));
        assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_None)));
        assert((POuter.checkConstruct<int&, int const&, int&&>(O, ptr)));
        A.destroy(ptr);
        ::operator delete((void*)ptr);
    }
    PInner.reset();
    POuter.reset();
}


// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
// is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is
// true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
//     allocator_arg, inner_allocator(), std::forward<Args>(args)...).
void test_bullet_two() {
    using VoidAlloc2 = CountingAllocator<void, 2>;

    AllocController POuter;
    AllocController PInner;
    {
        using T = UsesAllocatorV1<VoidAlloc2, 3>;
        using Outer = CountingAllocator<T, 1>;
        using Inner = CountingAllocator<T, 2>;
        using SA = std::scoped_allocator_adaptor<Outer, Inner>;
        static_assert(!std::uses_allocator<T, Outer>::value, "");
        static_assert(std::uses_allocator<T, Inner>::value, "");
        T* ptr = (T*)::operator new(sizeof(T));
        Outer O(POuter);
        Inner I(PInner);
        SA A(O, I);
        int x = 42;
        int const& cx = x;
        A.construct(ptr, x, cx, std::move(x));
        assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I)));
        assert((POuter.checkConstruct<std::allocator_arg_t const&,
                   SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
        A.destroy(ptr);
        ::operator delete((void*)ptr);
    }
    PInner.reset();
    POuter.reset();
}

// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
// is_constructible_v<T, Args..., inner_allocator_type&> is true, calls
// OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
//   std::forward<Args>(args)..., inner_allocator()).
void test_bullet_three() {
    using VoidAlloc2 = CountingAllocator<void, 2>;

    AllocController POuter;
    AllocController PInner;
    {
        using T = UsesAllocatorV2<VoidAlloc2, 3>;
        using Outer = CountingAllocator<T, 1>;
        using Inner = CountingAllocator<T, 2>;
        using SA = std::scoped_allocator_adaptor<Outer, Inner>;
        static_assert(!std::uses_allocator<T, Outer>::value, "");
        static_assert(std::uses_allocator<T, Inner>::value, "");
        T* ptr = (T*)::operator new(sizeof(T));
        Outer O(POuter);
        Inner I(PInner);
        SA A(O, I);
        int x = 42;
        int const& cx = x;
        A.construct(ptr, x, cx, std::move(x));
        assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I)));
        assert((POuter.checkConstruct<
                   int&, int const&, int&&,
                   SA::inner_allocator_type&>(O, ptr)));
        A.destroy(ptr);
        ::operator delete((void*)ptr);
    }
    PInner.reset();
    POuter.reset();
}

int main(int, char**) {
    test_bullet_one();
    test_bullet_two();
    test_bullet_three();

  return 0;
}
