//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <tuple>

// template <class... Types> class tuple;

// template <class Alloc, class... UTypes>
//   tuple(allocator_arg_t, const Alloc& a, UTypes&&...);

// UNSUPPORTED: c++98, c++03

#include <tuple>
#include <cassert>

#include "MoveOnly.h"
#include "allocators.h"
#include "../alloc_first.h"
#include "../alloc_last.h"

template <class T = void>
struct DefaultCtorBlowsUp {
  constexpr DefaultCtorBlowsUp() {
      static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated");
  }

  explicit constexpr DefaultCtorBlowsUp(int x) : value(x) {}

  int value;
};


struct DerivedFromAllocArgT : std::allocator_arg_t {};


// Make sure the _Up... constructor SFINAEs out when the number of initializers
// is less that the number of elements in the tuple. Previously libc++ would
// offer these constructers as an extension but they broke conforming code.
void test_uses_allocator_sfinae_evaluation()
{
     using BadDefault = DefaultCtorBlowsUp<>;
    {
        typedef std::tuple<MoveOnly, MoveOnly, BadDefault> Tuple;

        static_assert(!std::is_constructible<
            Tuple,
            std::allocator_arg_t, A1<int>, MoveOnly
        >::value, "");

        static_assert(std::is_constructible<
            Tuple,
            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault
        >::value, "");
    }
    {
        typedef std::tuple<MoveOnly, MoveOnly, BadDefault, BadDefault> Tuple;

        static_assert(!std::is_constructible<
            Tuple,
            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly
        >::value, "");

        static_assert(std::is_constructible<
            Tuple,
            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault, BadDefault
        >::value, "");
    }
}

int main()
{
    {
        std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0));
        assert(std::get<0>(t) == 0);
    }
    {
        using T = DefaultCtorBlowsUp<>;
        std::tuple<T> t(std::allocator_arg, A1<int>(), T(42));
        assert(std::get<0>(t).value == 42);
    }
    {
        std::tuple<MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
                                         MoveOnly(0), MoveOnly(1));
        assert(std::get<0>(t) == 0);
        assert(std::get<1>(t) == 1);
    }
    {
        using T = DefaultCtorBlowsUp<>;
        std::tuple<T, T> t(std::allocator_arg, A1<int>(), T(42), T(43));
        assert(std::get<0>(t).value == 42);
        assert(std::get<1>(t).value == 43);
    }
    {
        std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(),
                                                   MoveOnly(0),
                                                   1, 2);
        assert(std::get<0>(t) == 0);
        assert(std::get<1>(t) == 1);
        assert(std::get<2>(t) == 2);
    }
    {
        using T = DefaultCtorBlowsUp<>;
        std::tuple<T, T, T> t(std::allocator_arg, A1<int>(), T(1), T(2), T(3));
        assert(std::get<0>(t).value == 1);
        assert(std::get<1>(t).value == 2);
        assert(std::get<2>(t).value == 3);
    }
    {
        alloc_first::allocator_constructed = false;
        alloc_last::allocator_constructed = false;
        std::tuple<int, alloc_first, alloc_last> t(std::allocator_arg,
                                                   A1<int>(5), 1, 2, 3);
        assert(std::get<0>(t) == 1);
        assert(alloc_first::allocator_constructed);
        assert(std::get<1>(t) == alloc_first(2));
        assert(alloc_last::allocator_constructed);
        assert(std::get<2>(t) == alloc_last(3));
    }
    {
        // Check that uses-allocator construction is still selected when
        // given a tag type that derives from allocator_arg_t.
        DerivedFromAllocArgT tag;
        alloc_first::allocator_constructed = false;
        alloc_last::allocator_constructed = false;
        std::tuple<int, alloc_first, alloc_last> t(tag,
                                                   A1<int>(5), 1, 2, 3);
        assert(std::get<0>(t) == 1);
        assert(alloc_first::allocator_constructed);
        assert(std::get<1>(t) == alloc_first(2));
        assert(alloc_last::allocator_constructed);
        assert(std::get<2>(t) == alloc_last(3));
    }
    // Stress test the SFINAE on the uses-allocator constructors and
    // ensure that the "reduced-arity-initialization" extension is not offered
    // for these constructors.
    test_uses_allocator_sfinae_evaluation();
}
