Convert factory functions to return std::unique_ptrs.

https://github.com/ceres-solver/ceres-solver/issues/755

Change-Id: I8ff028ca6082a5f448f3891214af03971d565937
diff --git a/internal/ceres/block_jacobian_writer.cc b/internal/ceres/block_jacobian_writer.cc
index a5020e6..b8cb3c7 100644
--- a/internal/ceres/block_jacobian_writer.cc
+++ b/internal/ceres/block_jacobian_writer.cc
@@ -138,12 +138,12 @@
 
 // Create evaluate prepareres that point directly into the final jacobian. This
 // makes the final Write() a nop.
-BlockEvaluatePreparer* BlockJacobianWriter::CreateEvaluatePreparers(
-    int num_threads) {
+std::unique_ptr<BlockEvaluatePreparer[]>
+BlockJacobianWriter::CreateEvaluatePreparers(int num_threads) {
   int max_derivatives_per_residual_block =
       program_->MaxDerivativesPerResidualBlock();
 
-  BlockEvaluatePreparer* preparers = new BlockEvaluatePreparer[num_threads];
+  auto preparers = std::make_unique<BlockEvaluatePreparer[]>(num_threads);
   for (int i = 0; i < num_threads; i++) {
     preparers[i].Init(&jacobian_layout_[0], max_derivatives_per_residual_block);
   }
diff --git a/internal/ceres/block_jacobian_writer.h b/internal/ceres/block_jacobian_writer.h
index b9c918b..2bf584c 100644
--- a/internal/ceres/block_jacobian_writer.h
+++ b/internal/ceres/block_jacobian_writer.h
@@ -59,7 +59,8 @@
 
   // Create evaluate prepareres that point directly into the final jacobian.
   // This makes the final Write() a nop.
-  BlockEvaluatePreparer* CreateEvaluatePreparers(int num_threads);
+  std::unique_ptr<BlockEvaluatePreparer[]> CreateEvaluatePreparers(
+      int num_threads);
 
   std::unique_ptr<SparseMatrix> CreateJacobian() const;
 
diff --git a/internal/ceres/compressed_row_jacobian_writer.h b/internal/ceres/compressed_row_jacobian_writer.h
index 2765a58..a73d0c6 100644
--- a/internal/ceres/compressed_row_jacobian_writer.h
+++ b/internal/ceres/compressed_row_jacobian_writer.h
@@ -33,6 +33,7 @@
 #ifndef CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
 #define CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
 
+#include <memory>
 #include <utility>
 #include <vector>
 
@@ -89,7 +90,8 @@
   // assumed by the cost functions, use scratch space to store the
   // jacobians temporarily then copy them over to the larger jacobian
   // in the Write() function.
-  ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) {
+  std::unique_ptr<ScratchEvaluatePreparer[]> CreateEvaluatePreparers(
+      int num_threads) {
     return ScratchEvaluatePreparer::Create(*program_, num_threads);
   }
 
diff --git a/internal/ceres/dense_jacobian_writer.h b/internal/ceres/dense_jacobian_writer.h
index 0d86819..26f1715 100644
--- a/internal/ceres/dense_jacobian_writer.h
+++ b/internal/ceres/dense_jacobian_writer.h
@@ -33,6 +33,8 @@
 #ifndef CERES_INTERNAL_DENSE_JACOBIAN_WRITER_H_
 #define CERES_INTERNAL_DENSE_JACOBIAN_WRITER_H_
 
+#include <memory>
+
 #include "ceres/casts.h"
 #include "ceres/dense_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
@@ -54,7 +56,8 @@
   // Since the dense matrix has different layout than that assumed by the cost
   // functions, use scratch space to store the jacobians temporarily then copy
   // them over to the larger jacobian later.
-  ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) {
+  std::unique_ptr<ScratchEvaluatePreparer[]> CreateEvaluatePreparers(
+      int num_threads) {
     return ScratchEvaluatePreparer::Create(*program_, num_threads);
   }
 
diff --git a/internal/ceres/dynamic_compressed_row_jacobian_writer.cc b/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
index f6bb3b3..b261926 100644
--- a/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
+++ b/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
@@ -43,7 +43,7 @@
 using std::pair;
 using std::vector;
 
-ScratchEvaluatePreparer*
+std::unique_ptr<ScratchEvaluatePreparer[]>
 DynamicCompressedRowJacobianWriter::CreateEvaluatePreparers(int num_threads) {
   return ScratchEvaluatePreparer::Create(*program_, num_threads);
 }
diff --git a/internal/ceres/dynamic_compressed_row_jacobian_writer.h b/internal/ceres/dynamic_compressed_row_jacobian_writer.h
index b9858ba..9a93b2b 100644
--- a/internal/ceres/dynamic_compressed_row_jacobian_writer.h
+++ b/internal/ceres/dynamic_compressed_row_jacobian_writer.h
@@ -55,7 +55,8 @@
   // the cost functions. The scratch space is therefore used to store
   // the jacobians (including zeros) temporarily before only the non-zero
   // entries are copied over to the larger jacobian in `Write`.
-  ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads);
+  std::unique_ptr<ScratchEvaluatePreparer[]> CreateEvaluatePreparers(
+      int num_threads);
 
   // Return a `DynamicCompressedRowSparseMatrix` which is filled by
   // `Write`. Note that `Finalize` must be called to make the
diff --git a/internal/ceres/gradient_checking_cost_function.cc b/internal/ceres/gradient_checking_cost_function.cc
index 1bb9ec9..fdd378e 100644
--- a/internal/ceres/gradient_checking_cost_function.cc
+++ b/internal/ceres/gradient_checking_cost_function.cc
@@ -80,7 +80,6 @@
     set_num_residuals(function->num_residuals());
   }
 
-
   bool Evaluate(double const* const* parameters,
                 double* residuals,
                 double** jacobians) const final {
@@ -143,6 +142,7 @@
   }
   return SOLVER_CONTINUE;
 }
+
 void GradientCheckingIterationCallback::SetGradientErrorDetected(
     std::string& error_log) {
   std::lock_guard<std::mutex> l(mutex_);
@@ -150,7 +150,7 @@
   error_log_ += "\n" + error_log;
 }
 
-CostFunction* CreateGradientCheckingCostFunction(
+std::unique_ptr<CostFunction> CreateGradientCheckingCostFunction(
     const CostFunction* cost_function,
     const std::vector<const Manifold*>* manifolds,
     double relative_step_size,
@@ -160,12 +160,12 @@
   NumericDiffOptions numeric_diff_options;
   numeric_diff_options.relative_step_size = relative_step_size;
 
-  return new GradientCheckingCostFunction(cost_function,
-                                          manifolds,
-                                          numeric_diff_options,
-                                          relative_precision,
-                                          extra_info,
-                                          callback);
+  return std::make_unique<GradientCheckingCostFunction>(cost_function,
+                                                        manifolds,
+                                                        numeric_diff_options,
+                                                        relative_precision,
+                                                        extra_info,
+                                                        callback);
 }
 
 std::unique_ptr<ProblemImpl> CreateGradientCheckingProblemImpl(
diff --git a/internal/ceres/gradient_checking_cost_function.h b/internal/ceres/gradient_checking_cost_function.h
index b21d113..e514ae6 100644
--- a/internal/ceres/gradient_checking_cost_function.h
+++ b/internal/ceres/gradient_checking_cost_function.h
@@ -73,7 +73,8 @@
 // with finite differences. This API is only intended for unit tests that intend
 // to  check the functionality of the GradientCheckingCostFunction
 // implementation directly.
-CERES_EXPORT_INTERNAL CostFunction* CreateGradientCheckingCostFunction(
+CERES_EXPORT_INTERNAL std::unique_ptr<CostFunction>
+CreateGradientCheckingCostFunction(
     const CostFunction* cost_function,
     const std::vector<const Manifold*>* manifolds,
     double relative_step_size,
diff --git a/internal/ceres/gradient_checking_cost_function_test.cc b/internal/ceres/gradient_checking_cost_function_test.cc
index 5e6b64c..9994efa 100644
--- a/internal/ceres/gradient_checking_cost_function_test.cc
+++ b/internal/ceres/gradient_checking_cost_function_test.cc
@@ -164,13 +164,13 @@
 
   TestTerm<-1, -1> term(arity, dim);
   GradientCheckingIterationCallback callback;
-  std::unique_ptr<CostFunction> gradient_checking_cost_function(
+  auto gradient_checking_cost_function =
       CreateGradientCheckingCostFunction(&term,
                                          nullptr,
                                          kRelativeStepSize,
                                          kRelativePrecision,
                                          "Ignored.",
-                                         &callback));
+                                         &callback);
   term.Evaluate(&parameters[0], &original_residual, &original_jacobians[0]);
 
   gradient_checking_cost_function->Evaluate(
@@ -220,13 +220,13 @@
   {
     TestTerm<1, 2> term(arity, dim);
     GradientCheckingIterationCallback callback;
-    std::unique_ptr<CostFunction> gradient_checking_cost_function(
+    auto gradient_checking_cost_function =
         CreateGradientCheckingCostFunction(&term,
                                            nullptr,
                                            kRelativeStepSize,
                                            kRelativePrecision,
                                            "Fuzzy banana",
-                                           &callback));
+                                           &callback);
     EXPECT_TRUE(gradient_checking_cost_function->Evaluate(
         &parameters[0], &residual, &jacobians[0]));
     EXPECT_TRUE(callback.gradient_error_detected());
@@ -240,13 +240,13 @@
   {
     TestTerm<-1, -1> term(arity, dim);
     GradientCheckingIterationCallback callback;
-    std::unique_ptr<CostFunction> gradient_checking_cost_function(
+    auto gradient_checking_cost_function =
         CreateGradientCheckingCostFunction(&term,
                                            nullptr,
                                            kRelativeStepSize,
                                            kRelativePrecision,
                                            "Fuzzy banana",
-                                           &callback));
+                                           &callback);
     EXPECT_TRUE(gradient_checking_cost_function->Evaluate(
         &parameters[0], &residual, &jacobians[0]));
     EXPECT_FALSE(callback.gradient_error_detected());
@@ -365,7 +365,7 @@
   // clang-format on
 
   GradientCheckingIterationCallback callback;
-  std::unique_ptr<ProblemImpl> gradient_checking_problem_impl =
+  auto gradient_checking_problem_impl =
       CreateGradientCheckingProblemImpl(&problem_impl, 1.0, 1.0, &callback);
 
   // The dimensions of the two problems match.
@@ -443,7 +443,7 @@
   // clang-format on
 
   GradientCheckingIterationCallback callback;
-  std::unique_ptr<ProblemImpl> gradient_checking_problem_impl =
+  auto gradient_checking_problem_impl =
       CreateGradientCheckingProblemImpl(&problem_impl, 1.0, 1.0, &callback);
 
   // The dimensions of the two problems match.
@@ -504,7 +504,7 @@
   problem_impl.SetParameterUpperBound(x, 1, 2.5);
 
   GradientCheckingIterationCallback callback;
-  std::unique_ptr<ProblemImpl> gradient_checking_problem_impl =
+  auto gradient_checking_problem_impl =
       CreateGradientCheckingProblemImpl(&problem_impl, 1.0, 1.0, &callback);
 
   // The dimensions of the two problems match.
diff --git a/internal/ceres/graph_algorithms.h b/internal/ceres/graph_algorithms.h
index 7d63b33..82a20d8 100644
--- a/internal/ceres/graph_algorithms.h
+++ b/internal/ceres/graph_algorithms.h
@@ -257,11 +257,11 @@
 // spanning forest, or a collection of linear paths that span the
 // graph G.
 template <typename Vertex>
-WeightedGraph<Vertex>* Degree2MaximumSpanningForest(
+std::unique_ptr<WeightedGraph<Vertex>> Degree2MaximumSpanningForest(
     const WeightedGraph<Vertex>& graph) {
   // Array of edges sorted in decreasing order of their weights.
   std::vector<std::pair<double, std::pair<Vertex, Vertex>>> weighted_edges;
-  WeightedGraph<Vertex>* forest = new WeightedGraph<Vertex>();
+  auto forest = std::make_unique<WeightedGraph<Vertex>>();
 
   // Disjoint-set to keep track of the connected components in the
   // maximum spanning tree.
diff --git a/internal/ceres/minimizer.cc b/internal/ceres/minimizer.cc
index 8562968..a3c77cb 100644
--- a/internal/ceres/minimizer.cc
+++ b/internal/ceres/minimizer.cc
@@ -38,13 +38,13 @@
 namespace ceres {
 namespace internal {
 
-Minimizer* Minimizer::Create(MinimizerType minimizer_type) {
+std::unique_ptr<Minimizer> Minimizer::Create(MinimizerType minimizer_type) {
   if (minimizer_type == TRUST_REGION) {
-    return new TrustRegionMinimizer;
+    return std::make_unique<TrustRegionMinimizer>();
   }
 
   if (minimizer_type == LINE_SEARCH) {
-    return new LineSearchMinimizer;
+    return std::make_unique<LineSearchMinimizer>();
   }
 
   LOG(FATAL) << "Unknown minimizer_type: " << minimizer_type;
diff --git a/internal/ceres/minimizer.h b/internal/ceres/minimizer.h
index 246550d..326b325 100644
--- a/internal/ceres/minimizer.h
+++ b/internal/ceres/minimizer.h
@@ -178,7 +178,7 @@
     std::shared_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
   };
 
-  static Minimizer* Create(MinimizerType minimizer_type);
+  static std::unique_ptr<Minimizer> Create(MinimizerType minimizer_type);
   static bool RunCallbacks(const Options& options,
                            const IterationSummary& iteration_summary,
                            Solver::Summary* summary);
diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc
index d16e6dd..50a30c9 100644
--- a/internal/ceres/parameter_block_ordering.cc
+++ b/internal/ceres/parameter_block_ordering.cc
@@ -54,7 +54,7 @@
   CHECK(ordering != nullptr);
   ordering->clear();
   EventLogger event_logger("ComputeStableSchurOrdering");
-  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
+  auto graph = CreateHessianGraph(program);
   event_logger.AddEvent("CreateHessianGraph");
 
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
@@ -86,7 +86,7 @@
   CHECK(ordering != nullptr);
   ordering->clear();
 
-  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
+  auto graph = CreateHessianGraph(program);
   int independent_set_size = IndependentSetOrdering(*graph, ordering);
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
 
@@ -106,7 +106,7 @@
   CHECK(ordering != nullptr);
   ordering->Clear();
   const vector<ParameterBlock*> parameter_blocks = program.parameter_blocks();
-  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
+  auto graph = CreateHessianGraph(program);
 
   int num_covered = 0;
   int round = 0;
@@ -124,8 +124,9 @@
   }
 }
 
-Graph<ParameterBlock*>* CreateHessianGraph(const Program& program) {
-  Graph<ParameterBlock*>* graph = new Graph<ParameterBlock*>;
+std::unique_ptr<Graph<ParameterBlock*>> CreateHessianGraph(
+    const Program& program) {
+  auto graph = std::make_unique<Graph<ParameterBlock*>>();
   CHECK(graph != nullptr);
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
   for (int i = 0; i < parameter_blocks.size(); ++i) {
diff --git a/internal/ceres/parameter_block_ordering.h b/internal/ceres/parameter_block_ordering.h
index 82ab75d..d9b3210 100644
--- a/internal/ceres/parameter_block_ordering.h
+++ b/internal/ceres/parameter_block_ordering.h
@@ -31,6 +31,7 @@
 #ifndef CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
 #define CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
 
+#include <memory>
 #include <vector>
 
 #include "ceres/graph.h"
@@ -78,8 +79,8 @@
 // vertex corresponds to a parameter block in the Problem except for
 // parameter blocks that are marked constant. An edge connects two
 // parameter blocks, if they co-occur in a residual block.
-CERES_EXPORT_INTERNAL Graph<ParameterBlock*>* CreateHessianGraph(
-    const Program& program);
+CERES_EXPORT_INTERNAL std::unique_ptr<Graph<ParameterBlock*>>
+CreateHessianGraph(const Program& program);
 
 // Iterate over each of the groups in order of their priority and fill
 // summary with their sizes.
diff --git a/internal/ceres/parameter_block_ordering_test.cc b/internal/ceres/parameter_block_ordering_test.cc
index fd24839..a64f81b 100644
--- a/internal/ceres/parameter_block_ordering_test.cc
+++ b/internal/ceres/parameter_block_ordering_test.cc
@@ -46,9 +46,6 @@
 namespace ceres {
 namespace internal {
 
-using std::vector;
-
-typedef Graph<ParameterBlock*> HessianGraph;
 typedef std::unordered_set<ParameterBlock*> VertexSet;
 
 template <int M, int... Ns>
@@ -85,8 +82,9 @@
 
 TEST_F(SchurOrderingTest, NoFixed) {
   const Program& program = problem_.program();
-  const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
-  std::unique_ptr<HessianGraph> graph(CreateHessianGraph(program));
+  const std::vector<ParameterBlock*>& parameter_blocks =
+      program.parameter_blocks();
+  auto graph = CreateHessianGraph(program);
 
   const VertexSet& vertices = graph->vertices();
   EXPECT_EQ(vertices.size(), 4);
@@ -131,7 +129,7 @@
   problem_.SetParameterBlockConstant(w_);
 
   const Program& program = problem_.program();
-  std::unique_ptr<HessianGraph> graph(CreateHessianGraph(program));
+  auto graph = CreateHessianGraph(program);
   EXPECT_EQ(graph->vertices().size(), 0);
 }
 
@@ -139,8 +137,9 @@
   problem_.SetParameterBlockConstant(x_);
 
   const Program& program = problem_.program();
-  const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
-  std::unique_ptr<HessianGraph> graph(CreateHessianGraph(program));
+  const std::vector<ParameterBlock*>& parameter_blocks =
+      program.parameter_blocks();
+  auto graph = CreateHessianGraph(program);
 
   const VertexSet& vertices = graph->vertices();
 
@@ -171,7 +170,7 @@
   }
 
   // The constant parameter block is at the end.
-  vector<ParameterBlock*> ordering;
+  std::vector<ParameterBlock*> ordering;
   ComputeSchurOrdering(program, &ordering);
   EXPECT_EQ(ordering.back(), parameter_blocks[0]);
 }
diff --git a/internal/ceres/preprocessor.cc b/internal/ceres/preprocessor.cc
index 1fcd74a..b9dc066 100644
--- a/internal/ceres/preprocessor.cc
+++ b/internal/ceres/preprocessor.cc
@@ -41,13 +41,14 @@
 namespace ceres {
 namespace internal {
 
-Preprocessor* Preprocessor::Create(MinimizerType minimizer_type) {
+std::unique_ptr<Preprocessor> Preprocessor::Create(
+    MinimizerType minimizer_type) {
   if (minimizer_type == TRUST_REGION) {
-    return new TrustRegionPreprocessor;
+    return std::make_unique<TrustRegionPreprocessor>();
   }
 
   if (minimizer_type == LINE_SEARCH) {
-    return new LineSearchPreprocessor;
+    return std::make_unique<LineSearchPreprocessor>();
   }
 
   LOG(FATAL) << "Unknown minimizer_type: " << minimizer_type;
diff --git a/internal/ceres/preprocessor.h b/internal/ceres/preprocessor.h
index ec56c6e..7dc74cc 100644
--- a/internal/ceres/preprocessor.h
+++ b/internal/ceres/preprocessor.h
@@ -70,7 +70,7 @@
 class CERES_EXPORT_INTERNAL Preprocessor {
  public:
   // Factory.
-  static Preprocessor* Create(MinimizerType minimizer_type);
+  static std::unique_ptr<Preprocessor> Create(MinimizerType minimizer_type);
   virtual ~Preprocessor();
   virtual bool Preprocess(const Solver::Options& options,
                           ProblemImpl* problem,
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index 2ab52da..c009719 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -61,9 +61,11 @@
 //     // Evaluator::CreateJacobian.
 //     std::unique_ptr<SparseMatrix> CreateJacobian() const;
 //
-//     // Create num_threads evaluate preparers. Caller owns result which must
-//     // be freed with delete[]. Resulting preparers are valid while *this is.
-//     EvaluatePreparer* CreateEvaluatePreparers(int num_threads);
+//     // Create num_threads evaluate preparers.Resulting preparers are valid
+//     // while *this is.
+//
+//     std::unique_ptr<EvaluatePreparer[]> CreateEvaluatePreparers(
+//                                           int num_threads);
 //
 //     // Write the block jacobians from a residual block evaluation to the
 //     // larger sparse jacobian.
@@ -115,8 +117,8 @@
       : options_(options),
         program_(program),
         jacobian_writer_(options, program),
-        evaluate_preparers_(
-            jacobian_writer_.CreateEvaluatePreparers(options.num_threads)) {
+        evaluate_preparers_(std::move(
+            jacobian_writer_.CreateEvaluatePreparers(options.num_threads))) {
 #ifdef CERES_NO_THREADS
     if (options_.num_threads > 1) {
       LOG(WARNING) << "No threading support is compiled into this binary; "
diff --git a/internal/ceres/scratch_evaluate_preparer.cc b/internal/ceres/scratch_evaluate_preparer.cc
index a59694e..f7589f6 100644
--- a/internal/ceres/scratch_evaluate_preparer.cc
+++ b/internal/ceres/scratch_evaluate_preparer.cc
@@ -37,9 +37,9 @@
 namespace ceres {
 namespace internal {
 
-ScratchEvaluatePreparer* ScratchEvaluatePreparer::Create(const Program& program,
-                                                         int num_threads) {
-  ScratchEvaluatePreparer* preparers = new ScratchEvaluatePreparer[num_threads];
+std::unique_ptr<ScratchEvaluatePreparer[]> ScratchEvaluatePreparer::Create(
+    const Program& program, int num_threads) {
+  auto preparers = std::make_unique<ScratchEvaluatePreparer[]>(num_threads);
   int max_derivatives_per_residual_block =
       program.MaxDerivativesPerResidualBlock();
   for (int i = 0; i < num_threads; i++) {
diff --git a/internal/ceres/scratch_evaluate_preparer.h b/internal/ceres/scratch_evaluate_preparer.h
index 2d2745d..d0ecc3d 100644
--- a/internal/ceres/scratch_evaluate_preparer.h
+++ b/internal/ceres/scratch_evaluate_preparer.h
@@ -47,8 +47,8 @@
 class ScratchEvaluatePreparer {
  public:
   // Create num_threads ScratchEvaluatePreparers.
-  static ScratchEvaluatePreparer* Create(const Program& program,
-                                         int num_threads);
+  static std::unique_ptr<ScratchEvaluatePreparer[]> Create(
+      const Program& program, int num_threads);
 
   // EvaluatePreparer interface
   void Init(int max_derivatives_per_residual_block);
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index 1d2420c..6561f18 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -436,8 +436,7 @@
   }
 
   const Vector original_reduced_parameters = pp->reduced_parameters;
-  std::unique_ptr<Minimizer> minimizer(
-      Minimizer::Create(pp->options.minimizer_type));
+  auto minimizer = Minimizer::Create(pp->options.minimizer_type);
   minimizer->Minimize(
       pp->minimizer_options, pp->reduced_parameters.data(), summary);
 
@@ -534,8 +533,7 @@
   // The main thread also does work so we only need to launch num_threads - 1.
   problem_impl->context()->EnsureMinimumThreads(options.num_threads - 1);
 
-  std::unique_ptr<Preprocessor> preprocessor(
-      Preprocessor::Create(modified_options.minimizer_type));
+  auto preprocessor = Preprocessor::Create(modified_options.minimizer_type);
   PreprocessedProblem pp;
 
   const bool status =
diff --git a/internal/ceres/sparse_cholesky_test.cc b/internal/ceres/sparse_cholesky_test.cc
index 2ef24e3..363f991 100644
--- a/internal/ceres/sparse_cholesky_test.cc
+++ b/internal/ceres/sparse_cholesky_test.cc
@@ -51,10 +51,11 @@
 
 namespace {
 
-BlockSparseMatrix* CreateRandomFullRankMatrix(const int num_col_blocks,
-                                              const int min_col_block_size,
-                                              const int max_col_block_size,
-                                              const double block_density) {
+std::unique_ptr<BlockSparseMatrix> CreateRandomFullRankMatrix(
+    const int num_col_blocks,
+    const int min_col_block_size,
+    const int max_col_block_size,
+    const double block_density) {
   // Create a random matrix
   BlockSparseMatrix::RandomMatrixOptions options;
   options.num_col_blocks = num_col_blocks;
@@ -65,16 +66,14 @@
   options.min_row_block_size = 1;
   options.max_row_block_size = max_col_block_size;
   options.block_density = block_density;
-  std::unique_ptr<BlockSparseMatrix> random_matrix(
-      BlockSparseMatrix::CreateRandomMatrix(options));
+  auto random_matrix = BlockSparseMatrix::CreateRandomMatrix(options);
 
   // Add a diagonal block sparse matrix to make it full rank.
   Vector diagonal = Vector::Ones(random_matrix->num_cols());
-  std::unique_ptr<BlockSparseMatrix> block_diagonal(
-      BlockSparseMatrix::CreateDiagonalMatrix(
-          diagonal.data(), random_matrix->block_structure()->cols));
+  auto block_diagonal = BlockSparseMatrix::CreateDiagonalMatrix(
+      diagonal.data(), random_matrix->block_structure()->cols);
   random_matrix->AppendRows(*block_diagonal);
-  return random_matrix.release();
+  return random_matrix;
 }
 
 static bool ComputeExpectedSolution(const CompressedRowSparseMatrix& lhs,
@@ -115,15 +114,13 @@
   sparse_cholesky_options.sparse_linear_algebra_library_type =
       sparse_linear_algebra_library_type;
   sparse_cholesky_options.use_postordering = (ordering_type == AMD);
-  std::unique_ptr<SparseCholesky> sparse_cholesky =
-      SparseCholesky::Create(sparse_cholesky_options);
+  auto sparse_cholesky = SparseCholesky::Create(sparse_cholesky_options);
   const CompressedRowSparseMatrix::StorageType storage_type =
       sparse_cholesky->StorageType();
 
-  std::unique_ptr<BlockSparseMatrix> m(CreateRandomFullRankMatrix(
-      num_blocks, min_block_size, max_block_size, block_density));
-  std::unique_ptr<InnerProductComputer> inner_product_computer(
-      InnerProductComputer::Create(*m, storage_type));
+  auto m = CreateRandomFullRankMatrix(
+      num_blocks, min_block_size, max_block_size, block_density);
+  auto inner_product_computer = InnerProductComputer::Create(*m, storage_type);
   inner_product_computer->Compute();
   CompressedRowSparseMatrix* lhs = inner_product_computer->mutable_result();
 
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index 06f31ec..54de638 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -79,7 +79,7 @@
   }
 }
 
-WeightedGraph<int>* CreateSchurComplementGraph(
+std::unique_ptr<WeightedGraph<int>> CreateSchurComplementGraph(
     const vector<set<int>>& visibility) {
   const time_t start_time = time(nullptr);
   // Compute the number of e_blocks/point blocks. Since the visibility
@@ -121,7 +121,7 @@
     }
   }
 
-  WeightedGraph<int>* graph = new WeightedGraph<int>;
+  auto graph = std::make_unique<WeightedGraph<int>>();
 
   // Add vertices and initialize the pairs for self edges so that self
   // edges are guaranteed. This is needed for the Canonical views
diff --git a/internal/ceres/visibility.h b/internal/ceres/visibility.h
index 68c6723..e86bb88 100644
--- a/internal/ceres/visibility.h
+++ b/internal/ceres/visibility.h
@@ -35,6 +35,7 @@
 #ifndef CERES_INTERNAL_VISIBILITY_H_
 #define CERES_INTERNAL_VISIBILITY_H_
 
+#include <memory>
 #include <set>
 #include <vector>
 
@@ -72,8 +73,8 @@
 //
 // Caller acquires ownership of the returned WeightedGraph pointer
 // (heap-allocated).
-CERES_EXPORT_INTERNAL WeightedGraph<int>* CreateSchurComplementGraph(
-    const std::vector<std::set<int>>& visibility);
+CERES_EXPORT_INTERNAL std::unique_ptr<WeightedGraph<int>>
+CreateSchurComplementGraph(const std::vector<std::set<int>>& visibility);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index 3e3604f..9419e6b 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -162,11 +162,9 @@
   // maximum spanning forest of this graph.
   vector<set<int>> cluster_visibility;
   ComputeClusterVisibility(visibility, &cluster_visibility);
-  std::unique_ptr<WeightedGraph<int>> cluster_graph(
-      CreateClusterGraph(cluster_visibility));
+  auto cluster_graph = CreateClusterGraph(cluster_visibility);
   CHECK(cluster_graph != nullptr);
-  std::unique_ptr<WeightedGraph<int>> forest(
-      Degree2MaximumSpanningForest(*cluster_graph));
+  auto forest = Degree2MaximumSpanningForest(*cluster_graph);
   CHECK(forest != nullptr);
   ForestToClusterPairs(*forest, &cluster_pairs_);
 }
@@ -187,8 +185,7 @@
 // memberships for each camera block.
 void VisibilityBasedPreconditioner::ClusterCameras(
     const vector<set<int>>& visibility) {
-  std::unique_ptr<WeightedGraph<int>> schur_complement_graph(
-      CreateSchurComplementGraph(visibility));
+  auto schur_complement_graph = CreateSchurComplementGraph(visibility);
   CHECK(schur_complement_graph != nullptr);
 
   std::unordered_map<int, int> membership;
@@ -503,9 +500,10 @@
 // Construct a graph whose vertices are the clusters, and the edge
 // weights are the number of 3D points visible to cameras in both the
 // vertices.
-WeightedGraph<int>* VisibilityBasedPreconditioner::CreateClusterGraph(
+std::unique_ptr<WeightedGraph<int>>
+VisibilityBasedPreconditioner::CreateClusterGraph(
     const vector<set<int>>& cluster_visibility) const {
-  WeightedGraph<int>* cluster_graph = new WeightedGraph<int>;
+  auto cluster_graph = std::make_unique<WeightedGraph<int>>();
 
   for (int i = 0; i < num_clusters_; ++i) {
     cluster_graph->AddVertex(i);
diff --git a/internal/ceres/visibility_based_preconditioner.h b/internal/ceres/visibility_based_preconditioner.h
index 0da42a2..1150d33 100644
--- a/internal/ceres/visibility_based_preconditioner.h
+++ b/internal/ceres/visibility_based_preconditioner.h
@@ -160,7 +160,7 @@
   void ComputeClusterVisibility(
       const std::vector<std::set<int>>& visibility,
       std::vector<std::set<int>>* cluster_visibility) const;
-  WeightedGraph<int>* CreateClusterGraph(
+  std::unique_ptr<WeightedGraph<int>> CreateClusterGraph(
       const std::vector<std::set<int>>& visibility) const;
   void ForestToClusterPairs(
       const WeightedGraph<int>& forest,