// 2001-12-27 pme
//
// Copyright (C) 2001, 2002, 2003, 2004, 2005 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 2, 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 COPYING.  If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.

// 23.2.1.1 deque constructors, copy, and assignment

#include <deque>
#include <iterator>
#include <sstream>
#include <testsuite_allocator.h>
#include <testsuite_hooks.h>

using __gnu_test::copy_tracker;
using __gnu_test::tracker_allocator_counter;
using __gnu_test::tracker_allocator;
using __gnu_test::copy_constructor;
using __gnu_test::assignment_operator;
using __gnu_test::counter;
using __gnu_test::destructor;

typedef std::deque<counter>   gdeque;

bool test __attribute__((unused)) = true;

// 23.2.1     required types
//
// A missing required type will cause a compile failure.
//
void
requiredTypesCheck()
{
  typedef int             T;
  typedef std::deque<T>   X;

  typedef X::reference              reference;
  typedef X::const_reference        const_reference;
  typedef X::iterator               iterator;
  typedef X::const_iterator         const_iterator;
  typedef X::size_type              size_type;
  typedef X::difference_type        difference_type;
  typedef X::value_type             value_type;
  typedef X::allocator_type         allocator_type;
  typedef X::pointer                pointer;
  typedef X::const_pointer          const_pointer;
  typedef X::reverse_iterator       reverse_iterator;
  typedef X::const_reverse_iterator const_reverse_iterator;
}


// @fn defaultConstructorCheck
// Explicitly checks the default deque constructor and destructor for both
// trivial and non-trivial types.  In addition, the size() and empty()
// member functions are explicitly checked here since it should be their
// first use. Checking those functions means checking the begin() and
// end() and their const brethren functions as well.
//
// @verbatim
// 23.2.1.1   default ctor/dtor
//  effects:
//    23.2.1.1        constructs an empty deque using the specified allocator
//  postconditions:
//    23.1 table 65   u.size() == 0
//  throws:
//  complexity:
//    23.1 table 65   constant
//
// 23.2.1.2   bool empty() const
//  semantics:
//    23.1 table 65   a.size() == 0
//    23.1 (7)        a.begin() == a.end()
//  throws:
//  complexity:
//    23.1 table 65   constant
//
// 23.2.1.2   size_type size() const
//  semantics:
//    23.1 table 65   a.end() - a.begin()
//  throws:
//  complexity:
//    23.1 table 65(A) should be constant
//
// 23.2.1     iterator begin()
//            const_iterator begin() const
//            iterator end() 
//            const_iterator end() const
//  throws:
//    23.1 (10) pt. 4 does not throw
//  complexity:
//    23.1 table 65   constant
// @endverbatim
void
defaultConstructorCheckPOD()
{
  // setup
  typedef int             T;
  typedef std::deque<T>   X;

  // run test
  X u;

  // assert postconditions
  VERIFY(u.empty());
  VERIFY(0 == u.size());
  VERIFY(u.begin() == u.end());
  VERIFY(0 == std::distance(u.begin(), u.end()));

  // teardown
}


void
defaultConstructorCheck()
{
  // setup
  typedef copy_tracker  T;
  typedef std::deque<T>     X;

  copy_tracker::reset();

  // run test
  const X u;

  // assert postconditions
  VERIFY(u.empty());
  VERIFY(0 == u.size());
  VERIFY(u.begin() == u.end());
  VERIFY(0 == std::distance(u.begin(), u.end()));

  // teardown
}


// @fn copyConstructorCheck()
// Explicitly checks the deque copy constructor.  Continues verificaton of
// ancillary member functions documented under defaultConstructorCheck().
//
// This check also tests the push_back() member function.
//
// @verbatim
// 23.2.1     copy constructor
//  effects:
//  postconditions:
//    22.1.1 table 65 a == X(a)
//                    u == a
//  throws:
//  complexity:
//    22.1.1 table 65 linear
// @endverbatim
void
copyConstructorCheck()
{
  // setup
  typedef copy_tracker  T;
  typedef std::deque<T>     X;

  const std::size_t copyBaseSize = 17;  // arbitrary

  X a;
  for (std::size_t i = 0; i < copyBaseSize; ++i)
    a.push_back(i);
  copy_tracker::reset();

  // assert preconditions
  VERIFY(!a.empty());
  VERIFY(copyBaseSize == a.size());
  VERIFY(a.begin() != a.end());
  VERIFY( copyBaseSize == static_cast<std::size_t>(std::distance(a.begin(), a.end())) );

  // run test
  X u = a;

  // assert postconditions
  VERIFY(u == a);
  VERIFY(copyBaseSize == copy_constructor::count());

  // teardown
}


// @fn fillConstructorCheck()
// This test explicitly verifies the basic fill constructor.  Like the default
// constructor, later tests depend on the fill constructor working correctly.
// That means this explicit test should preceed the later tests so the error
// message given on assertion failure can be more helpful n tracking the
// problem.
// 
// 23.2.1.1   fill constructor
//  complexity:
//    23.2.1.1        linear in N
void
fillConstructorCheck()
{
  // setup
  typedef copy_tracker  T;
  typedef std::deque<T>   X;

  const X::size_type  n(23);  
  const X::value_type t(111);

  copy_tracker::reset();

  // run test
  X a(n, t);

  // assert postconditions
  VERIFY(n == a.size());
  VERIFY(n == copy_constructor::count());

  // teardown
}


// @fn fillConstructorCheck2()
// Explicit check for fill constructors masqueraded as range constructors as
// elucidated in clause 23.1.1 paragraph 9 of the standard.
//
// 23.1.1 (9) fill constructor looking like a range constructor
void
fillConstructorCheck2()
{
  typedef copy_tracker  T;
  typedef std::deque<T>   X;

  const std::size_t f = 23;  
  const std::size_t l = 111;

  copy_tracker::reset();

  X a(f, l);

  VERIFY(f == a.size());
  VERIFY(f == copy_constructor::count());
}


// @fn rangeConstructorCheckForwardIterator()
// This test copies from one deque to another to force the copy
// constructor for T to be used because the compiler will kindly
// elide copies if the default constructor can be used with
// type conversions.  Trust me.
//
// 23.2.1.1   range constructor, forward iterators
void
rangeConstructorCheckForwardIterator()
{
  // setup
  typedef copy_tracker  T;
  typedef std::deque<T>   X;

  const X::size_type  n(726); 
  const X::value_type t(307);
  X source(n, t);
  X::iterator i = source.begin();
  X::iterator j = source.end();
  X::size_type rangeSize = std::distance(i, j);

  copy_tracker::reset();

  // test
  X a(i, j);

  // assert postconditions
  VERIFY(rangeSize == a.size());
  VERIFY(copy_constructor::count() <= rangeSize);
}


// @fn rangeConstructorCheckInputIterator()
// An explicit check for range construction on an input iterator
// range, which the standard expounds upon as having a different
// complexity than forward iterators.
//
// 23.2.1.1   range constructor, input iterators
void
rangeConstructorCheckInputIterator()
{
  typedef copy_tracker  T;
  typedef std::deque<T>     X;

  std::istringstream ibuf("1234567890123456789");
  const X::size_type rangeSize = ibuf.str().size();  
  std::istream_iterator<char>  i(ibuf);
  std::istream_iterator<char>  j;

  copy_tracker::reset();

  X a(i, j);

  VERIFY(rangeSize == a.size());
  VERIFY(copy_constructor::count() <= (2 * rangeSize));
}


// 23.2.1     copy assignment
void
copyAssignmentCheck()
{
  typedef copy_tracker  T;
  typedef std::deque<T>     X;

  const X::size_type  n(18);  
  const X::value_type t(1023);
  X a(n, t);
  X r;

  copy_tracker::reset();

  r = a;

  VERIFY(r == a);
  VERIFY(n == copy_constructor::count());
}


// 23.2.1.1   fill assignment
//
// The complexity check must check dtors+copyAssign and
// copyCtor+copyAssign because that's the way the SGI implementation
// works.  Dunno if it's true standard compliant (which specifies fill
// assignment in terms of erase and insert only), but it should work
// as (most) users expect and is more efficient.
void
fillAssignmentCheck()
{
  typedef copy_tracker  T;
  typedef std::deque<T>   X;

  const X::size_type  starting_size(10);  
  const X::value_type starting_value(66);
  const X::size_type  n(23);  
  const X::value_type t(111);

  X a(starting_size, starting_value);
  copy_tracker::reset();

  // preconditions
  VERIFY(starting_size == a.size());

  // test
  a.assign(n, t);

  // postconditions
  VERIFY(n == a.size());
  VERIFY(n == (copy_constructor::count() + assignment_operator::count()));
  VERIFY(starting_size == (destructor::count() + assignment_operator::count()));
}


// @verbatim
// 23.2.1     range assignment
// 23.2.1.1   deque constructors, copy, and assignment
//  effects:
//  Constructs a deque equal to the range [first, last), using the
//  specified allocator.
//
//      template<typename InputIterator>
//        assign(InputIterator first, InputIterator last);
//      
//    is equivalent to
//
//      erase(begin(), end());
//      insert(begin(), first, last);
//
//  postconditions:
//  throws:
//  complexity:
//    forward iterators: N calls to the copy constructor, 0 reallocations
//    input iterators:   2N calls to the copy constructor, log(N) reallocations
// @endverbatim
void
rangeAssignmentCheck()
{
  typedef copy_tracker  T;
  typedef std::deque<T>   X;

  const X::size_type  source_size(726); 
  const X::value_type source_value(307);
  const X::size_type  starting_size(10);  
  const X::value_type starting_value(66);

  X source(source_size, source_value);
  X::iterator i = source.begin();
  X::iterator j = source.end();
  X::size_type rangeSize = std::distance(i, j);

  X a(starting_size, starting_value);
  VERIFY(starting_size == a.size());

  copy_tracker::reset();

  a.assign(i, j);

  VERIFY(source == a);
  VERIFY(rangeSize == (copy_constructor::count() + assignment_operator::count()));
  VERIFY(starting_size == (destructor::count() + assignment_operator::count()));
}


// 23.1 (10)  range assignment
// 23.2.1.3   with exception
void
rangeAssignmentCheckWithException()
{
  // setup
  typedef copy_tracker T;
  typedef std::deque<T>    X;

  // test
  // What does "no effects" mean?
}


// 23.1.1 (9) fill assignment looking like a range assignment
void
fillAssignmentCheck2()
{
  // setup
  typedef copy_tracker T;
  typedef std::deque<T>    X;

  // test
  // What does "no effects" mean?
}

// Verify that the default deque constructor offers the basic exception
// guarantee.
void
test_default_ctor_exception_safety()
{
  // setup
  typedef copy_tracker T;
  typedef std::deque<T, tracker_allocator<T> > X;

  T::reset();
  copy_constructor::throw_on(3);
  tracker_allocator_counter::reset();

  // test
  try
  {
    X a(7);
    VERIFY( false );
  }
  catch (...)
  {
  }

  // assert postconditions
  VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());

  // teardown
}

// Verify that the copy constructor offers the basic exception guarantee.
void
test_copy_ctor_exception_safety()
{
  // setup
  typedef copy_tracker T;
  typedef std::deque<T, tracker_allocator<T> > X;

  tracker_allocator_counter::reset();
  {
    X a(7);
    T::reset();
    copy_constructor::throw_on(3);


    // test
    try
    {
      X u(a);
      VERIFY(false);
    }
    catch (...)
    {
    }
  }

  // assert postconditions
  VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());

  // teardown
}

int main()
{
  // basic functionality and standard conformance checks
  requiredTypesCheck();
  defaultConstructorCheckPOD();
  defaultConstructorCheck();
  test_default_ctor_exception_safety();
  copyConstructorCheck();
  test_copy_ctor_exception_safety();
  fillConstructorCheck();
  fillConstructorCheck2();
  rangeConstructorCheckInputIterator();
  rangeConstructorCheckForwardIterator();
  copyAssignmentCheck();
  fillAssignmentCheck();
  fillAssignmentCheck2();
  rangeAssignmentCheck();
  rangeAssignmentCheckWithException();
  return 0;
}
