AutoDiffCostFunction: optional ownership

Add Ownership semantics to the AutoDiffCostFunction

This allows several benefits, such as pointer ordering always being the
same for numerical repeatability (due to blocks being ordered by
pointer address), memory adjacency for better cache performance, and
reduced allocator pressure / overhead.

This is then made use of in libmv by preallocating the errors and
cost functions into vectors

Change-Id: Ia5b97e7249b55a463264b6e26f7a02291927c9f2
diff --git a/docs/source/automatic_derivatives.rst b/docs/source/automatic_derivatives.rst
index 0c48c80..e15e911 100644
--- a/docs/source/automatic_derivatives.rst
+++ b/docs/source/automatic_derivatives.rst
@@ -266,7 +266,6 @@
 
 Indeed, this is essentially how :class:`AutoDiffCostFunction` works.
 
-
 Pitfalls
 ========
 
diff --git a/docs/source/nnls_modeling.rst b/docs/source/nnls_modeling.rst
index b260cab..d30df1c 100644
--- a/docs/source/nnls_modeling.rst
+++ b/docs/source/nnls_modeling.rst
@@ -268,6 +268,21 @@
    computing a 1-dimensional output from two arguments, both
    2-dimensional.
 
+   By default :class:`AutoDiffCostFunction` will take ownership of the cost
+   functor pointer passed to it, ie. will call `delete` on the cost functor
+   when the :class:`AutoDiffCostFunction` itself is deleted. However, this may
+   be undesirable in certain cases, therefore it is also possible to specify
+   :class:`DO_NOT_TAKE_OWNERSHIP` as a second argument in the constructor,
+   while passing a pointer to a cost functor which does not need to be deleted
+   by the AutoDiffCostFunction. For example:
+
+   .. code-block:: c++
+
+    MyScalarCostFunctor functor(1.0)
+    CostFunction* cost_function
+        = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
+            &functor, DO_NOT_TAKE_OWNERSHIP);
+
    :class:`AutoDiffCostFunction` also supports cost functions with a
    runtime-determined number of residuals. For example:
 
diff --git a/examples/libmv_bundle_adjuster.cc b/examples/libmv_bundle_adjuster.cc
index be93678..22bcf5b 100644
--- a/examples/libmv_bundle_adjuster.cc
+++ b/examples/libmv_bundle_adjuster.cc
@@ -654,6 +654,7 @@
   PrintCameraIntrinsics("Original intrinsics: ", camera_intrinsics);
 
   ceres::Problem::Options problem_options;
+  problem_options.cost_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP;
   ceres::Problem problem(problem_options);
 
   // Convert cameras rotations to angle axis and merge with translation
@@ -678,6 +679,11 @@
         new ceres::SubsetParameterization(6, constant_translation);
   }
 
+  std::vector<OpenCVReprojectionError> errors;
+  std::vector<ceres::AutoDiffCostFunction<OpenCVReprojectionError, 2, 8, 6, 3>> costFunctions;
+  errors.reserve(all_markers.size());
+  costFunctions.reserve(all_markers.size());
+
   int num_residuals = 0;
   bool have_locked_camera = false;
   for (int i = 0; i < all_markers.size(); ++i) {
@@ -692,11 +698,10 @@
     // camera translaiton.
     double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
 
-    problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
-        OpenCVReprojectionError, 2, 8, 6, 3>(
-            new OpenCVReprojectionError(
-                marker.x,
-                marker.y)),
+    errors.emplace_back(marker.x, marker.y);
+    costFunctions.emplace_back(&errors.back(), ceres::DO_NOT_TAKE_OWNERSHIP);
+
+    problem.AddResidualBlock(&costFunctions.back(),
         NULL,
         camera_intrinsics,
         current_camera_R_t,
diff --git a/include/ceres/autodiff_cost_function.h b/include/ceres/autodiff_cost_function.h
index 5e6e9c5..8a22538 100644
--- a/include/ceres/autodiff_cost_function.h
+++ b/include/ceres/autodiff_cost_function.h
@@ -153,28 +153,44 @@
           int... Ns>          // Number of parameters in each parameter block.
 class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals, Ns...> {
  public:
-  // Takes ownership of functor. Uses the template-provided value for the
-  // number of residuals ("kNumResiduals").
-  explicit AutoDiffCostFunction(CostFunctor* functor) : functor_(functor) {
+  // Takes ownership of functor by default. Uses the template-provided value for
+  // the number of residuals ("kNumResiduals").
+  explicit AutoDiffCostFunction(CostFunctor* functor,
+                                Ownership ownership = TAKE_OWNERSHIP)
+      : functor_(functor), ownership_(ownership) {
     static_assert(kNumResiduals != DYNAMIC,
                   "Can't run the fixed-size constructor if the number of "
                   "residuals is set to ceres::DYNAMIC.");
   }
 
-  // Takes ownership of functor. Ignores the template-provided
+  // Takes ownership of functor by default. Ignores the template-provided
   // kNumResiduals in favor of the "num_residuals" argument provided.
   //
   // This allows for having autodiff cost functions which return varying
   // numbers of residuals at runtime.
-  AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
-      : functor_(functor) {
+  explicit AutoDiffCostFunction(CostFunctor* functor,
+                                int num_residuals,
+                                Ownership ownership = TAKE_OWNERSHIP)
+      : functor_(functor), ownership_(ownership) {
     static_assert(kNumResiduals == DYNAMIC,
                   "Can't run the dynamic-size constructor if the number of "
                   "residuals is not ceres::DYNAMIC.");
     SizedCostFunction<kNumResiduals, Ns...>::set_num_residuals(num_residuals);
   }
 
-  virtual ~AutoDiffCostFunction() {}
+  explicit AutoDiffCostFunction(AutoDiffCostFunction&& other)
+      : functor_(std::move(other.functor_)), ownership_(other.ownership_) {}
+
+  virtual ~AutoDiffCostFunction() {
+    // Manually release pointer if configured to not take ownership rather than
+    // deleting only if ownership is taken.
+    // This is to stay maximally compatible to old user code which may have
+    // forgotten to implement a virtual destructor, from when the
+    // AutoDiffCostFunction always took ownership.
+    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
+      functor_.release();
+    }
+  }
 
   // Implementation details follow; clients of the autodiff cost function should
   // not have to examine below here.
@@ -201,6 +217,7 @@
 
  private:
   std::unique_ptr<CostFunctor> functor_;
+  Ownership ownership_;
 };
 
 }  // namespace ceres