Callback support for unbound reference and array arguments.

Because the callback object uses const An& for the type of the Run() function in argument forwarding, the code breaks for An=T& or An=T[].  This CL adds in code to modify the parameter type to remove duplicate references, and other fun.

BUG=35223
TEST=new unittests

Review URL: http://codereview.chromium.org/6718021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79239 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 061808b..b3e01608 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -174,6 +174,10 @@
   return p.value;
 }
 
+void RefArgSet(int &n) {
+  n = 2;
+}
+
 // Only useful in no-compile tests.
 int UnwrapNoRefParentRef(Parent& p) {
   return p.value;
@@ -351,6 +355,37 @@
   EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
 }
 
+// Unbound argument type support tests.
+//   - Unbound value.
+//   - Unbound pointer.
+//   - Unbound reference.
+//   - Unbound const reference.
+//   - Unbound unsized array.
+//   - Unbound sized array.
+//   - Unbound array-of-arrays.
+TEST_F(BindTest, UnboundArgumentTypeSupport) {
+  Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic1<int>);
+  Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic1<int*>);
+  Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic1<int&>);
+  Callback<void(const int&)> unbound_const_ref_cb =
+      Bind(&VoidPolymorphic1<const int&>);
+  Callback<void(int[])> unbound_unsized_array_cb =
+      Bind(&VoidPolymorphic1<int[]>);
+  Callback<void(int[2])> unbound_sized_array_cb =
+      Bind(&VoidPolymorphic1<int[2]>);
+  Callback<void(int[][2])> unbound_array_of_arrays_cb =
+      Bind(&VoidPolymorphic1<int[][2]>);
+}
+
+// Function with unbound reference parameter.
+//   - Original paraemter is modified by callback.
+TEST_F(BindTest, UnboundReferenceSupport) {
+  int n = 0;
+  Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
+  unbound_ref_cb.Run(n);
+  EXPECT_EQ(2, n);
+}
+
 // Functions that take reference parameters.
 //  - Forced reference parameter type still stores a copy.
 //  - Forced const reference parameter type still stores a copy.
@@ -570,14 +605,13 @@
   //
   // HasRef p[10];
   // Callback<void(void)> method_bound_to_array_cb =
-  //    Bind(&HasRef::VoidConstMethod0, p);
+  //     Bind(&HasRef::VoidConstMethod0, p);
   // method_bound_to_array_cb.Run();
 
   // - Refcounted types should not be bound as a raw pointer.
   // HasRef for_raw_ptr;
   // Callback<void(void)> ref_count_as_raw_ptr =
   //     Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
-  // ASSERT_EQ(&for_raw_ptr, ref_count_as_raw_ptr.Run());
 
 }