// Copyright David Abrahams 2008. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <algorithm> //for std::swap
#include <cstddef> //for std::size_t

namespace boost_swap_impl
{
  template<class T>
  void swap_impl(T& left, T& right)
  {
    using std::swap;//use std::swap if argument dependent lookup fails
    swap(left,right);
  }

  template<class T, std::size_t N>
  void swap_impl(T (& left)[N], T (& right)[N])
  {
    for (std::size_t i = 0; i < N; ++i)
    {
      ::boost_swap_impl::swap_impl(left[i], right[i]);
    }
  }
}

namespace boost
{
  namespace swap_adl_barrier
  {
    template<class T>
    void swap(T& left, T& right)
    {
      ::boost_swap_impl::swap_impl(left, right);
    }
  }

  using namespace swap_adl_barrier;
}

//Put test class in namespace boost
namespace boost
{
class swap_test_class
{
public:
  swap_test_class()
  {
    ++constructCount();
  }

  ~swap_test_class()
  {
    ++destructCount();
  }

  swap_test_class(const swap_test_class&)
  {
    ++copyCount();
    ++destructCount();
  }

  swap_test_class& operator=(const swap_test_class&)
  {
    ++copyCount();
    return *this;
  }

  void swap(swap_test_class& other)
  {
    ++swapCount();
  }


  static unsigned int swap_count(){ return swapCount(); }
  static unsigned int copy_count(){ return copyCount(); }
  static unsigned int construct_count(){ return constructCount(); }
  static unsigned int destruct_count(){ return destructCount(); }

  static void reset()
  {
    swapCount() = 0;
    copyCount() = 0;    
    constructCount() = 0;
    destructCount() = 0;
  }

private:
  static unsigned int& swapCount()
  {
    static unsigned int value = 0;
    return value;
  }

  static unsigned int& copyCount()    
  {
    static unsigned int value = 0;
    return value;
  }

  static unsigned int& constructCount()    
  {
    static unsigned int value = 0;
    return value;
  }

  static unsigned int& destructCount()    
  {
    static unsigned int value = 0;
    return value;
  }

};

}


int test_main(int, char*[])
{
  boost::swap_test_class object1;
  boost::swap_test_class object2;
  boost::swap(object1,object2);

  return 0;
}


