//===----------------------------------------------------------------------===//
//
// 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.h"
#include "controlled_allocators.h"

#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;
}
