// Boost.Function library

//  Copyright Douglas Gregor 2001-2003. Use, modification and
//  distribution is subject to 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)

// For more information, see http://www.boost.org

#include <boost/test/minimal.hpp>
#include <boost/function.hpp>
#include <functional>
#include <string>
#include <utility>

using ndnboost::function;
using std::string;

int global_int;

struct write_five_obj { void operator()() const { global_int = 5; } };
struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
static void write_five() { global_int = 5; }
static void write_three() { global_int = 3; }
struct generate_five_obj { int operator()() const { return 5; } };
struct generate_three_obj { int operator()() const { return 3; } };
static int generate_five() { return 5; }
static int generate_three() { return 3; }
static string identity_str(const string& s) { return s; }
static string string_cat(const string& s1, const string& s2) { return s1+s2; }
static int sum_ints(int x, int y) { return x+y; }

struct write_const_1_nonconst_2
{
  void operator()() { global_int = 2; }
  void operator()() const { global_int = 1; }
};

struct add_to_obj
{
  add_to_obj(int v) : value(v) {}

  int operator()(int x) const { return value + x; }

  int value;
};

static void
test_zero_args()
{
  typedef function<void ()> func_void_type;

  write_five_obj five;
  write_three_obj three;

  // Default construction
  func_void_type v1;
  BOOST_CHECK(v1.empty());

  // Assignment to an empty function
  v1 = five;
  BOOST_CHECK(v1 != 0);

  // Invocation of a function
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v1.clear();
  BOOST_CHECK(v1 == 0);

  // Assignment to an empty function
  v1 = three;
  BOOST_CHECK(!v1.empty());

  // Invocation and self-assignment
  global_int = 0;
  v1 = v1;
  v1();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v1 = five;

  // Invocation and self-assignment
  global_int = 0;
  v1 = (v1);
  v1();
  BOOST_CHECK(global_int == 5);

  // clear
  v1 = 0;
  BOOST_CHECK(0 == v1);

  // Assignment to an empty function from a free function
  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
  BOOST_CHECK(0 != v1);

  // Invocation
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
  BOOST_CHECK(!v1.empty());

  // Invocation
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 3);

  // Assignment
  v1 = five;
  BOOST_CHECK(!v1.empty());

  // Invocation
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v1 = &write_three;
  BOOST_CHECK(!v1.empty());

  // Invocation
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 3);

  // Construction from another function (that is empty)
  v1.clear();
  func_void_type v2(v1);
  BOOST_CHECK(!v2? true : false);

  // Assignment to an empty function
  v2 = three;
  BOOST_CHECK(!v2.empty());

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v2 = (five);

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 5);

  v2.clear();
  BOOST_CHECK(v2.empty());

  // Assignment to an empty function from a free function
  v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
  BOOST_CHECK(v2? true : false);

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
  BOOST_CHECK(!v2.empty());

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 3);

  // Swapping
  v1 = five;
  swap(v1, v2);
  v2();
  BOOST_CHECK(global_int == 5);
  v1();
  BOOST_CHECK(global_int == 3);
  swap(v1, v2);
  v1.clear();

  // Assignment
  v2 = five;
  BOOST_CHECK(!v2.empty());

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v2 = &write_three;
  BOOST_CHECK(!v2.empty());

  // Invocation
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 3);

  // Assignment to a function from an empty function
  v2 = v1;
  BOOST_CHECK(v2.empty());

  // Assignment to a function from a function with a functor
  v1 = three;
  v2 = v1;
  BOOST_CHECK(!v1.empty());
  BOOST_CHECK(!v2.empty());

  // Invocation
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 3);
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 3);

  // Assign to a function from a function with a function
  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
  v1 = v2;
  BOOST_CHECK(!v1.empty());
  BOOST_CHECK(!v2.empty());
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 5);
  global_int = 0;
  v2();
  BOOST_CHECK(global_int == 5);

  // Construct a function given another function containing a function
  func_void_type v3(v1);

  // Invocation of a function
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v3.clear();
  BOOST_CHECK(!v3? true : false);

  // Assignment to an empty function
  v3 = three;
  BOOST_CHECK(!v3.empty());

  // Invocation
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v3 = five;

  // Invocation
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 5);

  // clear()
  v3.clear();
  BOOST_CHECK(v3.empty());

  // Assignment to an empty function from a free function
  v3 = &write_five;
  BOOST_CHECK(!v3.empty());

  // Invocation
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v3 = &write_three;
  BOOST_CHECK(!v3.empty());

  // Invocation
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 3);

  // Assignment
  v3 = five;
  BOOST_CHECK(!v3.empty());

  // Invocation
  global_int = 0;
  v3();
  BOOST_CHECK(global_int == 5);

  // Construction of a function from a function containing a functor
  func_void_type v4(v3);

  // Invocation of a function
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v4.clear();
  BOOST_CHECK(v4.empty());

  // Assignment to an empty function
  v4 = three;
  BOOST_CHECK(!v4.empty());

  // Invocation
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v4 = five;

  // Invocation
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 5);

  // clear()
  v4.clear();
  BOOST_CHECK(v4.empty());

  // Assignment to an empty function from a free function
  v4 = &write_five;
  BOOST_CHECK(!v4.empty());

  // Invocation
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v4 = &write_three;
  BOOST_CHECK(!v4.empty());

  // Invocation
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 3);

  // Assignment
  v4 = five;
  BOOST_CHECK(!v4.empty());

  // Invocation
  global_int = 0;
  v4();
  BOOST_CHECK(global_int == 5);

  // Construction of a function from a functor
  func_void_type v5(five);

  // Invocation of a function
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v5.clear();
  BOOST_CHECK(v5.empty());

  // Assignment to an empty function
  v5 = three;
  BOOST_CHECK(!v5.empty());

  // Invocation
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v5 = five;

  // Invocation
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 5);

  // clear()
  v5.clear();
  BOOST_CHECK(v5.empty());

  // Assignment to an empty function from a free function
  v5 = &write_five;
  BOOST_CHECK(!v5.empty());

  // Invocation
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v5 = &write_three;
  BOOST_CHECK(!v5.empty());

  // Invocation
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 3);

  // Assignment
  v5 = five;
  BOOST_CHECK(!v5.empty());

  // Invocation
  global_int = 0;
  v5();
  BOOST_CHECK(global_int == 5);

  // Construction of a function from a function
  func_void_type v6(&write_five);

  // Invocation of a function
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v6.clear();
  BOOST_CHECK(v6.empty());

  // Assignment to an empty function
  v6 = three;
  BOOST_CHECK(!v6.empty());

  // Invocation
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 3);

  // Assignment to a non-empty function
  v6 = five;

  // Invocation
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 5);

  // clear()
  v6.clear();
  BOOST_CHECK(v6.empty());

  // Assignment to an empty function from a free function
  v6 = &write_five;
  BOOST_CHECK(!v6.empty());

  // Invocation
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 5);

  // Assignment to a non-empty function from a free function
  v6 = &write_three;
  BOOST_CHECK(!v6.empty());

  // Invocation
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 3);

  // Assignment
  v6 = five;
  BOOST_CHECK(!v6.empty());

  // Invocation
  global_int = 0;
  v6();
  BOOST_CHECK(global_int == 5);

  // Const vs. non-const
  write_const_1_nonconst_2 one_or_two;
  const function<void ()> v7(one_or_two);
  function<void ()> v8(one_or_two);

  global_int = 0;
  v7();
  BOOST_CHECK(global_int == 2);

  global_int = 0;
  v8();
  BOOST_CHECK(global_int == 2);

  // Test construction from 0 and comparison to 0
  func_void_type v9(0);
  BOOST_CHECK(v9 == 0);
  BOOST_CHECK(0 == v9);

  // Test return values
  typedef function<int ()> func_int_type;
  generate_five_obj gen_five;
  generate_three_obj gen_three;

  func_int_type i0(gen_five);

  BOOST_CHECK(i0() == 5);
  i0 = gen_three;
  BOOST_CHECK(i0() == 3);
  i0 = &generate_five;
  BOOST_CHECK(i0() == 5);
  i0 = &generate_three;
  BOOST_CHECK(i0() == 3);
  BOOST_CHECK(i0? true : false);
  i0.clear();
  BOOST_CHECK(!i0? true : false);

  // Test return values with compatible types
  typedef function<long ()> func_long_type;
  func_long_type i1(gen_five);

  BOOST_CHECK(i1() == 5);
  i1 = gen_three;
  BOOST_CHECK(i1() == 3);
  i1 = &generate_five;
  BOOST_CHECK(i1() == 5);
  i1 = &generate_three;
  BOOST_CHECK(i1() == 3);
  BOOST_CHECK(i1? true : false);
  i1.clear();
  BOOST_CHECK(!i1? true : false);
}

static void
test_one_arg()
{
  std::negate<int> neg;

  function<int (int)> f1(neg);
  BOOST_CHECK(f1(5) == -5);

  function<string (string)> id(&identity_str);
  BOOST_CHECK(id("str") == "str");

  function<string (const char*)> id2(&identity_str);
  BOOST_CHECK(id2("foo") == "foo");

  add_to_obj add_to(5);
  function<int (int)> f2(add_to);
  BOOST_CHECK(f2(3) == 8);

  const function<int (int)> cf2(add_to);
  BOOST_CHECK(cf2(3) == 8);
}

static void
test_two_args()
{
  function<string (const string&, const string&)> cat(&string_cat);
  BOOST_CHECK(cat("str", "ing") == "string");

  function<int (short, short)> sum(&sum_ints);
  BOOST_CHECK(sum(2, 3) == 5);
}

static void
test_emptiness()
{
  function<float ()> f1;
  BOOST_CHECK(f1.empty());

  function<float ()> f2;
  f2 = f1;
  BOOST_CHECK(f2.empty());

  function<double ()> f3;
  f3 = f2;
  BOOST_CHECK(f3.empty());
}

struct X {
  X(int v) : value(v) {}

  int twice() const { return 2*value; }
  int plus(int v) { return value + v; }

  int value;
};

static void
test_member_functions()
{
  ndnboost::function<int (X*)> f1(&X::twice);

  X one(1);
  X five(5);

  BOOST_CHECK(f1(&one) == 2);
  BOOST_CHECK(f1(&five) == 10);

  ndnboost::function<int (X*)> f1_2;
  f1_2 = &X::twice;

  BOOST_CHECK(f1_2(&one) == 2);
  BOOST_CHECK(f1_2(&five) == 10);

  ndnboost::function<int (X&, int)> f2(&X::plus);
  BOOST_CHECK(f2(one, 3) == 4);
  BOOST_CHECK(f2(five, 4) == 9);
}

struct add_with_throw_on_copy {
  int operator()(int x, int y) const { return x+y; }

  add_with_throw_on_copy() {}

  add_with_throw_on_copy(const add_with_throw_on_copy&)
  {
    throw std::runtime_error("But this CAN'T throw");
  }

  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
  {
    throw std::runtime_error("But this CAN'T throw");
  }
};

static void
test_ref()
{
  add_with_throw_on_copy atc;
  try {
    ndnboost::function<int (int, int)> f(ndnboost::ref(atc));
    BOOST_CHECK(f(1, 3) == 4);
  }
  catch(std::runtime_error e) {
    BOOST_ERROR("Nonthrowing constructor threw an exception");
  }
}

static void dummy() {}

static void test_empty_ref()
{
  ndnboost::function<void()> f1;
  ndnboost::function<void()> f2(ndnboost::ref(f1));

  try {
    f2();
    BOOST_ERROR("Exception didn't throw for reference to empty function.");
  }
  catch(std::runtime_error e) {}

  f1 = dummy;

  try {
    f2();
  }
  catch(std::runtime_error e) {
    BOOST_ERROR("Error calling referenced function.");
  }
}


static void test_exception()
{
  ndnboost::function<int (int, int)> f;
  try {
    f(5, 4);
    BOOST_CHECK(false);
  }
  catch(ndnboost::bad_function_call) {
    // okay
  }
}

typedef ndnboost::function< void * (void * reader) > reader_type;
typedef std::pair<int, reader_type> mapped_type;

static void test_implicit()
{
  mapped_type m;
  m = mapped_type();
}

static void test_call_obj(ndnboost::function<int (int, int)> f)
{
  BOOST_CHECK(!f.empty());
}

static void test_call_cref(const ndnboost::function<int (int, int)>& f)
{
  BOOST_CHECK(!f.empty());
}

static void test_call()
{
  test_call_obj(std::plus<int>());
  test_call_cref(std::plus<int>());
}

struct big_aggregating_structure {
  int disable_small_objects_optimizations[32];
    
  big_aggregating_structure()
  {
    ++ global_int;
  }
    
  big_aggregating_structure(const big_aggregating_structure&)
  {
    ++ global_int;
  }

  ~big_aggregating_structure()
  {
    -- global_int;
  }
    
  void operator()() 
  {
    ++ global_int;
  }

  void operator()(int) 
  {
    ++ global_int;
  }
};

template <class FunctionT>
static void test_move_semantics() 
{
  typedef FunctionT f1_type;

  big_aggregating_structure obj;
  
  f1_type f1 = obj;
  global_int = 0;
  f1();
  
  BOOST_CHECK(!f1.empty());
  BOOST_CHECK(global_int == 1);
  
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  // Testing rvalue constructors
  f1_type f2(static_cast<f1_type&&>(f1));
  BOOST_CHECK(f1.empty());
  BOOST_CHECK(!f2.empty());
  BOOST_CHECK(global_int == 1);
  f2();
  BOOST_CHECK(global_int == 2);
  
  f1_type f3(static_cast<f1_type&&>(f2));
  BOOST_CHECK(f1.empty());
  BOOST_CHECK(f2.empty());
  BOOST_CHECK(!f3.empty());
  BOOST_CHECK(global_int == 2);
  f3();
  BOOST_CHECK(global_int == 3);
    
  // Testing move assignment
  f1_type f4;
  BOOST_CHECK(f4.empty());
  f4 = static_cast<f1_type&&>(f3);
  BOOST_CHECK(f1.empty());
  BOOST_CHECK(f2.empty());
  BOOST_CHECK(f3.empty());
  BOOST_CHECK(!f4.empty());
  BOOST_CHECK(global_int == 3);
  f4();
  BOOST_CHECK(global_int == 4);
  
  // Testing self move assignment
  f4 = static_cast<f1_type&&>(f4);
  BOOST_CHECK(!f4.empty());
  BOOST_CHECK(global_int == 4);

  // Testing, that no memory leaked when assigning to nonempty function
  f4 = obj;
  BOOST_CHECK(!f4.empty());
  BOOST_CHECK(global_int == 4);
  f1_type f5 = obj;
  BOOST_CHECK(global_int == 5);
  f4 = static_cast<f1_type&&>(f5);
  BOOST_CHECK(global_int == 4);
  
#endif  
}

int test_main(int, char* [])
{
  test_zero_args();
  test_one_arg();
  test_two_args();
  test_emptiness();
  test_member_functions();
  test_ref();
  test_empty_ref();
  test_exception();
  test_implicit();
  test_call();
  test_move_semantics<function<void()> >();
  test_move_semantics<ndnboost::function0<void> >();

  return 0;
}
