// Copyright (C) 2019-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }

#include <testsuite_hooks.h>
#include <testsuite_allocator.h>

using test_allocator = __gnu_test::uneq_allocator<int>;

struct Arg { };

struct A
{
  A() : nargs(0) { }
  A(float&) : nargs(1) { }
  A(int, void*) : nargs(2) { }

  // These should not be used:
  A(const test_allocator& a);
  A(float&, const test_allocator& a);
  A(int, void*, const test_allocator& a);

  const int nargs;
  const int alloc_id = -1;

  // std::uses_allocator<A, test_allocator> should be false:
  using allocator_type = void*();
};

struct B
{
  // This means std::uses_allocator<B, test_allocator> is true:
  using allocator_type = test_allocator;

  B() : nargs(0) { }
  B(float&) : nargs(1) { }
  B(int, void*) : nargs(2) { }

  B(std::allocator_arg_t, const test_allocator& a)
  : nargs(0), alloc_id(a.get_personality()) { }
  B(std::allocator_arg_t, const test_allocator& a, float&)
  : nargs(1), alloc_id(a.get_personality()) { }
  B(std::allocator_arg_t, const test_allocator& a, int, void*)
  : nargs(2), alloc_id(a.get_personality()) { }
  B(std::allocator_arg_t, const test_allocator& a, B&& b)
  : nargs(b.nargs), alloc_id(a.get_personality()) { }

  // These should not be used:
  B(const test_allocator&);
  B(float&, const test_allocator&, float&);
  B(int, void*, const test_allocator&);
  B(const test_allocator&, float&);
  B(const test_allocator&, int, void*);
  B(B&&);
  B(B&&, const test_allocator&);

  const int nargs;
  const int alloc_id = -1;
};

struct C
{
  C() : nargs(0) { }
  C(float&) : nargs(1) { }
  C(int, void*) : nargs(2) { }

  C(const test_allocator& a)
  : nargs(0), alloc_id(a.get_personality()) { }
  C(float&, const test_allocator& a)
  : nargs(1), alloc_id(a.get_personality()) { }
  C(int, void*, const test_allocator& a)
  : nargs(2), alloc_id(a.get_personality()) { }
  C(C&& c, const test_allocator& a)
  : nargs(c.nargs), alloc_id(a.get_personality()) { }

  C(C&&);

  const int nargs;
  const int alloc_id = -1;
};

namespace std {
  // This means std::uses_allocator<C, test_allocator> is true:
  template<> struct uses_allocator<C, test_allocator> : std::true_type { };
}

test_allocator alloc1(1);
test_allocator alloc2(2);

void
test01()
{
  auto i0 = std::make_obj_using_allocator<int>(alloc1, 2);
  VERIFY( i0 == 2 );

  float f = 0.0f;

  auto a0 = std::make_obj_using_allocator<A>(alloc1);
  VERIFY( a0.nargs == 0 );
  VERIFY( a0.alloc_id == -1 );
  auto a1 = std::make_obj_using_allocator<A>(alloc1, f);
  VERIFY( a1.nargs == 1 );
  VERIFY( a1.alloc_id == -1 );
  auto a2 = std::make_obj_using_allocator<A>(alloc1, 123, nullptr);
  VERIFY( a2.nargs == 2 );
  VERIFY( a2.alloc_id == -1 );

  auto b0 = std::make_obj_using_allocator<B>(alloc1);
  VERIFY( b0.nargs == 0 );
  VERIFY( b0.alloc_id == 1 );
  auto b1 = std::make_obj_using_allocator<B>(alloc2, f);
  VERIFY( b1.nargs == 1 );
  VERIFY( b1.alloc_id == 2 );
  auto b2 = std::make_obj_using_allocator<B>(alloc1, 123, nullptr);
  VERIFY( b2.nargs == 2 );
  VERIFY( b2.alloc_id == 1 );

  auto c0 = std::make_obj_using_allocator<C>(alloc1);
  VERIFY( c0.nargs == 0 );
  VERIFY( c0.alloc_id == 1 );
  auto c1 = std::make_obj_using_allocator<C>(alloc2, f);
  VERIFY( c1.nargs == 1 );
  VERIFY( c1.alloc_id == 2 );
  auto c2 = std::make_obj_using_allocator<C>(alloc1, 123, nullptr);
  VERIFY( c2.nargs == 2 );
  VERIFY( c2.alloc_id == 1 );
}

void 
test02()
{
  decltype(auto) b
    = std::make_obj_using_allocator<const B>(alloc1, 123, nullptr);
  static_assert( std::is_const_v<decltype(b)> );
  VERIFY( b.nargs == 2 );
  VERIFY( b.alloc_id == 1 );

  decltype(auto) c = std::make_obj_using_allocator<const C>(alloc1);
  static_assert( std::is_const_v<decltype(c)> );
  VERIFY( c.nargs == 0 );
  VERIFY( c.alloc_id == 1 );
}

void
test03()
{
  B b;
  decltype(auto) ref = std::make_obj_using_allocator<B&>(alloc1, b);
  static_assert( std::is_same_v<decltype(ref), B&> );
  VERIFY( &ref == &b );
  VERIFY( ref.nargs == 0 );
  VERIFY( ref.alloc_id == -1 );
  const B& cref = std::make_obj_using_allocator<const B&>(alloc1, b);
  static_assert( std::is_same_v<decltype(cref), const B&> );
  VERIFY( &cref == &b );
  VERIFY( cref.nargs == 0 );
  VERIFY( cref.alloc_id == -1 );
}

void
test04()
{
  struct D
  {
    D(std::allocator_arg_t) { }
    D(std::allocator_arg_t, int) { }

    // These should not be used:
    D(std::allocator_arg_t, const test_allocator&);
    D(std::allocator_arg_t, const test_allocator&, int);

    ~D() { }
  };

  D d1 = std::make_obj_using_allocator<D>(alloc1, std::allocator_arg);

  struct E
  {
    using allocator_type = test_allocator;

    E(std::allocator_arg_t, const test_allocator&) { }
    E(std::allocator_arg_t, int, const test_allocator&) { }

    // These should not be used:
    E(std::allocator_arg_t);
    E(std::allocator_arg_t, int);

    ~E() { }
  };

  E e1 = std::make_obj_using_allocator<E>(alloc1, std::allocator_arg);
  E e2 = std::make_obj_using_allocator<E>(alloc2, std::allocator_arg, 2);
}

void
test05()
{
  using std::pair;
  std::piecewise_construct_t p;
  std::tuple<> t0;
  float f = 0.0f;
  std::tuple<float&> t1(f);
  std::tuple<int, void*> t2{};

  auto aa00 = std::make_obj_using_allocator<pair<A, A>>(alloc1, p, t0, t0);
  VERIFY( aa00.first.nargs == 0 );
  VERIFY( aa00.first.alloc_id == -1 );
  VERIFY( aa00.second.nargs == 0 );
  VERIFY( aa00.second.alloc_id == -1 );
  auto ab00 = std::make_obj_using_allocator<pair<A, B>>(alloc1, p, t0, t0);
  VERIFY( ab00.first.nargs == 0 );
  VERIFY( ab00.first.alloc_id == -1 );
  VERIFY( ab00.second.nargs == 0 );
  VERIFY( ab00.second.alloc_id == 1 );
  auto bc00 = std::make_obj_using_allocator<pair<B, C>>(alloc2, p, t0, t0);
  VERIFY( bc00.first.nargs == 0 );
  VERIFY( bc00.first.alloc_id == 2 );
  VERIFY( bc00.second.nargs == 0 );
  VERIFY( bc00.second.alloc_id == 2 );
  auto cb00 = std::make_obj_using_allocator<pair<C, B>>(alloc2, p, t0, t0);
  VERIFY( cb00.first.nargs == 0 );
  VERIFY( cb00.first.alloc_id == 2 );
  VERIFY( cb00.second.nargs == 0 );
  VERIFY( cb00.second.alloc_id == 2 );
  auto cc00
    = std::make_obj_using_allocator<pair<C, const C>>(alloc1, p, t0, t0);
  VERIFY( cc00.first.nargs == 0 );
  VERIFY( cc00.first.alloc_id == 1 );
  VERIFY( cc00.second.nargs == 0 );
  VERIFY( cc00.second.alloc_id == 1 );

  auto aa21 = std::make_obj_using_allocator<pair<A, A>>(alloc1, p, t2, t1);
  VERIFY( aa21.first.nargs == 2 );
  VERIFY( aa21.first.alloc_id == -1 );
  VERIFY( aa21.second.nargs == 1 );
  VERIFY( aa21.second.alloc_id == -1 );
  auto ab21 = std::make_obj_using_allocator<pair<A, B>>(alloc1, p, t2, t1);
  VERIFY( ab21.first.nargs == 2 );
  VERIFY( ab21.first.alloc_id == -1 );
  VERIFY( ab21.second.nargs == 1 );
  VERIFY( ab21.second.alloc_id == 1 );
  auto bc11 = std::make_obj_using_allocator<pair<B, C>>(alloc2, p, t1, t1);
  VERIFY( bc11.first.nargs == 1 );
  VERIFY( bc11.first.alloc_id == 2 );
  VERIFY( bc11.second.nargs == 1 );
  VERIFY( bc11.second.alloc_id == 2 );
  auto cb12 = std::make_obj_using_allocator<pair<C, B>>(alloc2, p, t1, t2);
  VERIFY( cb12.first.nargs == 1 );
  VERIFY( cb12.first.alloc_id == 2 );
  VERIFY( cb12.second.nargs == 2 );
  VERIFY( cb12.second.alloc_id == 2 );
  auto cc22
    = std::make_obj_using_allocator<pair<C, const C>>(alloc1, p, t2, t1);
  VERIFY( cc22.first.nargs == 2 );
  VERIFY( cc22.first.alloc_id == 1 );
  VERIFY( cc22.second.nargs == 1 );
  VERIFY( cc22.second.alloc_id == 1 );
}

void
test06()
{
  using std::pair;
  float f = 0.0f;

  auto aa00 = std::make_obj_using_allocator<pair<A, A>>(alloc1);
  VERIFY( aa00.first.nargs == 0 );
  VERIFY( aa00.first.alloc_id == -1 );
  VERIFY( aa00.second.nargs == 0 );
  VERIFY( aa00.second.alloc_id == -1 );
  auto ab00 = std::make_obj_using_allocator<pair<A, B>>(alloc1);
  VERIFY( ab00.first.nargs == 0 );
  VERIFY( ab00.first.alloc_id == -1 );
  VERIFY( ab00.second.nargs == 0 );
  VERIFY( ab00.second.alloc_id == 1 );
  auto bc00 = std::make_obj_using_allocator<pair<B, C>>(alloc2);
  VERIFY( bc00.first.nargs == 0 );
  VERIFY( bc00.first.alloc_id == 2 );
  VERIFY( bc00.second.nargs == 0 );
  VERIFY( bc00.second.alloc_id == 2 );
  auto cb00 = std::make_obj_using_allocator<pair<C, B>>(alloc2);
  VERIFY( cb00.first.nargs == 0 );
  VERIFY( cb00.first.alloc_id == 2 );
  VERIFY( cb00.second.nargs == 0 );
  VERIFY( cb00.second.alloc_id == 2 );
  auto cc00 = std::make_obj_using_allocator<pair<C, const C>>(alloc1);
  VERIFY( cc00.first.nargs == 0 );
  VERIFY( cc00.first.alloc_id == 1 );
  VERIFY( cc00.second.nargs == 0 );
  VERIFY( cc00.second.alloc_id == 1 );

  auto aa11 = std::make_obj_using_allocator<pair<A, A>>(alloc1, f, f);
  VERIFY( aa11.first.nargs == 1 );
  VERIFY( aa11.first.alloc_id == -1 );
  VERIFY( aa11.second.nargs == 1 );
  VERIFY( aa11.second.alloc_id == -1 );
  auto aba1 = std::make_obj_using_allocator<pair<A, B>>(alloc1, A{}, f);
  VERIFY( aba1.first.nargs == 0 );
  VERIFY( aba1.first.alloc_id == -1 );
  VERIFY( aba1.second.nargs == 1 );
  VERIFY( aba1.second.alloc_id == 1 );
  auto bc11 = std::make_obj_using_allocator<pair<B, C>>(alloc2, f, f);
  VERIFY( bc11.first.nargs == 1 );
  VERIFY( bc11.first.alloc_id == 2 );
  VERIFY( bc11.second.nargs == 1 );
  VERIFY( bc11.second.alloc_id == 2 );
  auto cb1b = std::make_obj_using_allocator<pair<C, B>>(alloc2, f, B{});
  VERIFY( cb1b.first.nargs == 1 );
  VERIFY( cb1b.first.alloc_id == 2 );
  VERIFY( cb1b.second.nargs == 0 );
  VERIFY( cb1b.second.alloc_id == 2 );
  auto cccc
    = std::make_obj_using_allocator<pair<C, const C>>(alloc1, C{}, C{});
  VERIFY( cccc.first.nargs == 0 );
  VERIFY( cccc.first.alloc_id == 1 );
  VERIFY( cccc.second.nargs == 0 );
  VERIFY( cccc.second.alloc_id == 1 );

  pair<float&, A> p1a(f, A{});
  pair<float&, float&> p11(f, f);
  auto aa1a = std::make_obj_using_allocator<pair<A, A>>(alloc1, p1a);
  VERIFY( aa1a.first.nargs == 1 );
  VERIFY( aa1a.first.alloc_id == -1 );
  VERIFY( aa1a.second.nargs == 0 );
  VERIFY( aa1a.second.alloc_id == -1 );
  auto ab11 = std::make_obj_using_allocator<pair<A, B>>(alloc1, p11);
  VERIFY( ab11.first.nargs == 1 );
  VERIFY( ab11.first.alloc_id == -1 );
  VERIFY( ab11.second.nargs == 1 );
  VERIFY( ab11.second.alloc_id == 1 );
  auto cb11 = std::make_obj_using_allocator<pair<C, B>>(alloc2, p11);
  VERIFY( cb11.first.nargs == 1 );
  VERIFY( cb11.first.alloc_id == 2 );
  VERIFY( cb11.second.nargs == 1 );
  VERIFY( cb11.second.alloc_id == 2 );

  auto bcbc = std::make_obj_using_allocator<pair<B, C>>(alloc2, pair<B, C>());
  VERIFY( bcbc.first.nargs == 0 );
  VERIFY( bcbc.first.alloc_id == 2 );
  VERIFY( bcbc.second.nargs == 0 );
  VERIFY( bcbc.second.alloc_id == 2 );

  auto cc11 = std::make_obj_using_allocator<pair<C, B>>(alloc2, std::move(p11));
  VERIFY( cc11.first.nargs == 1 );
  VERIFY( cc11.first.alloc_id == 2 );
  VERIFY( cc11.second.nargs == 1 );
  VERIFY( cc11.second.alloc_id == 2 );
}

void
test07()
{
  using nested_pair = std::pair<const std::pair<B, const B>, C>;
  auto p = std::make_obj_using_allocator<const nested_pair>(alloc1);
  VERIFY( p.first.first.alloc_id == 1 );
  VERIFY( p.first.second.alloc_id == 1 );
  VERIFY( p.second.alloc_id == 1 );
}

void
test08()
{
  // LWG DR 3187.
  // P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct()

  struct X {
    using allocator_type = std::allocator<X>;
    X(std::allocator_arg_t, allocator_type&&) { }
    X(const allocator_type&) { }
  };

  std::allocator<X> a;
  std::make_obj_using_allocator<X>(a);
}

int
main()
{
  test01();
  test02();
  test03();
  test04();
  test05();
  test06();
  test07();
  test08();
}
