Update minimum required C++ version for Ceres to C++14

- Removes all workarounds for pre-C++14 versions
- Removes '11' qualifier from C++ threading option and associated
  defines.
- Fix missing inclusion of 'Multithreading' in reported Ceres components
  when C++ threading model is enabled.
- Update Sphinx documentation to specify C++14 as minimum requirement.

Change-Id: I706c8b367b3221e3c4d1a0aaf669a8f9c911e438
This commit is contained in:
Alex Stewart
2020-05-30 11:30:01 +01:00
parent 1d75e75681
commit 7ef83e0759
35 changed files with 124 additions and 602 deletions
+10 -8
View File
@@ -32,19 +32,19 @@
cmake_minimum_required(VERSION 3.5)
cmake_policy(VERSION 3.5)
# Set the C++ version (must be >= C++11) when compiling Ceres.
# Set the C++ version (must be >= C++14) when compiling Ceres.
#
# Reflect a user-specified (via -D) CMAKE_CXX_STANDARD if present, otherwise
# default to C++11.
# default to C++14.
set(DEFAULT_CXX_STANDARD ${CMAKE_CXX_STANDARD})
if (NOT DEFAULT_CXX_STANDARD)
set(DEFAULT_CXX_STANDARD 11)
set(DEFAULT_CXX_STANDARD 14)
endif()
set(CMAKE_CXX_STANDARD ${DEFAULT_CXX_STANDARD} CACHE STRING
"C++ standard (minimum 11)" FORCE)
"C++ standard (minimum 14)" FORCE)
# Restrict CMAKE_CXX_STANDARD to the valid versions permitted and ensure that
# if one was forced via -D that it is in the valid set.
set(ALLOWED_CXX_STANDARDS 11 14 17 20)
set(ALLOWED_CXX_STANDARDS 14 17 20)
set_property(CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS ${ALLOWED_CXX_STANDARDS})
list(FIND ALLOWED_CXX_STANDARDS ${CMAKE_CXX_STANDARD} POSITION)
if (POSITION LESS 0)
@@ -56,11 +56,13 @@ endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "")
mark_as_advanced(CMAKE_CXX_STANDARD_REQUIRED)
# MSVC versions < 2013 did not fully support >= C++11.
# MSVC versions < 2015 did not fully support >= C++14, and technically even
# 2015 did not support a couple of smaller features
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
message(FATAL_ERROR "Invalid CMAKE_CXX_COMPILER_VERSION: "
"${CMAKE_CXX_COMPILER_VERSION}. Ceres requires at least MSVC 2013 Update 4+")
"${CMAKE_CXX_COMPILER_VERSION}. Ceres requires at least MSVC 2015 for "
"C++14 support.")
endif()
# On macOS, add the Homebrew prefix (with appropriate suffixes) to the
+1 -1
View File
@@ -196,7 +196,7 @@ def ceres_library(name,
"CERES_NO_ACCELERATE_SPARSE",
"CERES_NO_LAPACK",
"CERES_USE_EIGEN_SPARSE",
"CERES_USE_CXX11_THREADS",
"CERES_USE_CXX_THREADS",
],
includes = [
"config",
@@ -84,6 +84,8 @@ function(ceres_compile_options_to_components CURRENT_CERES_COMPILE_OPTIONS CERES
CERES_RESTRICT_SCHUR_SPECIALIZATION "SchurSpecializations")
add_to_output_if_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR}
CERES_USE_OPENMP "OpenMP;Multithreading")
add_to_output_if_found(CURRENT_CERES_COMPILE_OPTIONS ${CERES_COMPONENTS_VAR}
CERES_USE_CXX_THREADS "Multithreading")
# Remove duplicates of SparseLinearAlgebraLibrary if multiple sparse backends
# are present.
list(REMOVE_DUPLICATES ${CERES_COMPONENTS_VAR})
+3 -3
View File
@@ -29,7 +29,7 @@
# Author: alexs.mac@gmail.com (Alex Stewart)
# Ordered by expected preference.
set(CERES_THREADING_MODELS "CXX11_THREADS;OPENMP;NO_THREADS")
set(CERES_THREADING_MODELS "CXX_THREADS;OPENMP;NO_THREADS")
function(find_available_ceres_threading_models CERES_THREADING_MODELS_AVAILABLE_VAR)
set(CERES_THREADING_MODELS_AVAILABLE ${CERES_THREADING_MODELS})
@@ -48,7 +48,7 @@ function(find_available_ceres_threading_models CERES_THREADING_MODELS_AVAILABLE_
endfunction()
macro(set_ceres_threading_model_to_cxx11_threads)
list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX11_THREADS)
list(APPEND CERES_COMPILE_OPTIONS CERES_USE_CXX_THREADS)
endmacro()
macro(set_ceres_threading_model_to_openmp)
@@ -63,7 +63,7 @@ macro(set_ceres_threading_model_to_no_threads)
endmacro()
macro(set_ceres_threading_model CERES_THREADING_MODEL_TO_SET)
if ("${CERES_THREADING_MODEL_TO_SET}" STREQUAL "CXX11_THREADS")
if ("${CERES_THREADING_MODEL_TO_SET}" STREQUAL "CXX_THREADS")
set_ceres_threading_model_to_cxx11_threads()
elseif ("${CERES_THREADING_MODEL_TO_SET}" STREQUAL "OPENMP")
set_ceres_threading_model_to_openmp()
+3 -3
View File
@@ -73,10 +73,10 @@
// If defined, Ceres was compiled without multithreading support.
@CERES_NO_THREADS@
// If defined Ceres was compiled with OpenMP multithreading support.
// If defined Ceres was compiled with OpenMP multithreading.
@CERES_USE_OPENMP@
// If defined Ceres was compiled with C++11 thread support.
@CERES_USE_CXX11_THREADS@
// If defined Ceres was compiled with modern C++ multithreading.
@CERES_USE_CXX_THREADS@
// If defined, Ceres was built as a shared library.
@CERES_USING_SHARED_LIBRARY@
+3 -2
View File
@@ -54,8 +54,9 @@ Why?
of Non-linear Conjugate Gradients, BFGS and LBFGS.
* **Speed** - Ceres Solver has been extensively optimized, with C++
templating, hand written linear algebra routines and OpenMP or C++11 threads
based multithreading of the Jacobian evaluation and the linear solvers.
templating, hand written linear algebra routines and OpenMP or
modern C++ threads based multithreading of the Jacobian evaluation
and the linear solvers.
* **Solution Quality** Ceres is the `best performing`_ solver on the NIST
problem set used by Mondragon and Borchers for benchmarking
+4 -7
View File
@@ -23,9 +23,8 @@ Dependencies
.. NOTE ::
All versions of Ceres > 1.14 require a **fully C++11-compliant**
compiler. In versions <= 1.14, C++11 was an optional requirement
controlled by the ``CXX11 [Default: OFF]`` build option.
Starting with v2.0 Ceres requires a **fully C++14-compliant**
compiler. In versions <= 1.14, C++11 was an optional requirement.
Ceres relies on a number of open source libraries, some of which are
optional. For details on customizing the build process, see
@@ -378,7 +377,7 @@ Windows
<https://github.com/tbennun/ceres-windows>`_ for Ceres Solver by Tal
Ben-Nun.
On Windows, we support building with Visual Studio 2013 Release 4 or newer. Note
On Windows, we support building with Visual Studio 2015.2 of newer. Note
that the Windows port is less featureful and less tested than the
Linux or Mac OS X versions due to the lack of an officially supported
way of building SuiteSparse and CXSparse. There are however a number
@@ -709,7 +708,7 @@ Options controlling Ceres configuration
gains in the ``SPARSE_SCHUR`` solver, you can disable some of the
template specializations by turning this ``OFF``.
#. ``CERES_THREADING_MODEL [Default: CXX11_THREADS > OPENMP > NO_THREADS]``:
#. ``CERES_THREADING_MODEL [Default: CXX_THREADS > OPENMP > NO_THREADS]``:
Multi-threading backend Ceres should be compiled with. This will
automatically be set to only accept the available subset of threading
options in the CMake GUI.
@@ -904,8 +903,6 @@ The Ceres components which can be specified are:
#. ``Multithreading``: Ceres built with *a* multithreading library.
This is equivalent to (``CERES_THREAD != NO_THREADS``).
#. ``C++11``: Ceres built with C++11.
To specify one/multiple Ceres components use the ``COMPONENTS`` argument to
`find_package()
<http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_ like so:
+1 -1
View File
@@ -2226,7 +2226,7 @@ The three arrays will be:
Number of threads actually used by the solver for Jacobian and
residual evaluation. This number is not equal to
:member:`Solver::Summary::num_threads_given` if none of `OpenMP`
or `CXX11_THREADS` is available.
or `CXX_THREADS` is available.
.. member:: LinearSolverType Solver::Summary::linear_solver_type_given
+1 -3
View File
@@ -52,9 +52,7 @@ target_link_libraries(rosenbrock Ceres::ceres)
add_executable(curve_fitting_c curve_fitting.c)
target_link_libraries(curve_fitting_c Ceres::ceres)
# Force CMake to link curve_fitting_c using the C linker, this is important
# when Ceres was compiled using C++11 to ensure that -std=c++11 is not passed
# through.
# Force CMake to link curve_fitting_c using the C linker.
set_target_properties(curve_fitting_c PROPERTIES LINKER_LANGUAGE C)
# As this is a C file #including <math.h> we have to explicitly add the math
# library (libm). Although some compilers (dependent upon options) will accept
+3 -3
View File
@@ -89,12 +89,12 @@
#include <cstdint>
#include <numeric>
#include <tuple>
#include <utility>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/dynamic_cost_function_to_functor.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/integer_sequence.h"
#include "ceres/internal/parameter_dims.h"
#include "ceres/internal/port.h"
#include "ceres/types.h"
@@ -144,7 +144,7 @@ class CostFunctionToFunctor {
// Extract parameter block pointers from params.
using Indices =
internal::make_integer_sequence<int,
std::make_integer_sequence<int,
ParameterDims::kNumParameterBlocks>;
std::array<const T*, ParameterDims::kNumParameterBlocks> parameter_blocks =
GetParameterPointers<T>(params, Indices());
@@ -158,7 +158,7 @@ class CostFunctionToFunctor {
template <typename T, typename Tuple, int... Indices>
static std::array<const T*, ParameterDims::kNumParameterBlocks>
GetParameterPointers(const Tuple& paramPointers,
internal::integer_sequence<int, Indices...>) {
std::integer_sequence<int, Indices...>) {
return std::array<const T*, ParameterDims::kNumParameterBlocks>{
{std::get<Indices>(paramPointers)...}};
}
-122
View File
@@ -1,122 +0,0 @@
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: algorithm.h
// -----------------------------------------------------------------------------
//
// This header file contains Google extensions to the standard <algorithm> C++
// header.
#ifndef CERES_PUBLIC_INTERNAL_ALGORITHM_H_
#define CERES_PUBLIC_INTERNAL_ALGORITHM_H_
#include <algorithm>
#include <iterator>
#include <type_traits>
namespace ceres {
namespace internal {
// Performs comparisons with operator==, similar to C++14's `std::equal_to<>`.
struct EqualTo {
template <typename T, typename U>
bool operator()(const T& a, const U& b) const {
return a == b;
}
};
template <typename InputIter1, typename InputIter2, typename Pred>
bool EqualImpl(InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
InputIter2 last2,
Pred pred,
std::input_iterator_tag,
std::input_iterator_tag) {
while (true) {
if (first1 == last1) return first2 == last2;
if (first2 == last2) return false;
if (!pred(*first1, *first2)) return false;
++first1;
++first2;
}
}
template <typename InputIter1, typename InputIter2, typename Pred>
bool EqualImpl(InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
InputIter2 last2,
Pred&& pred,
std::random_access_iterator_tag,
std::random_access_iterator_tag) {
return (last1 - first1 == last2 - first2) &&
std::equal(first1, last1, first2, std::forward<Pred>(pred));
}
// When we are using our own internal predicate that just applies operator==, we
// forward to the non-predicate form of std::equal. This enables an optimization
// in libstdc++ that can result in std::memcmp being used for integer types.
template <typename InputIter1, typename InputIter2>
bool EqualImpl(InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
InputIter2 last2,
internal::EqualTo /* unused */,
std::random_access_iterator_tag,
std::random_access_iterator_tag) {
return (last1 - first1 == last2 - first2) &&
std::equal(first1, last1, first2);
}
// Compares the equality of two ranges specified by pairs of iterators, using
// the given predicate, returning true iff for each corresponding iterator i1
// and i2 in the first and second range respectively, pred(*i1, *i2) == true
//
// This comparison takes at most min(`last1` - `first1`, `last2` - `first2`)
// invocations of the predicate. Additionally, if InputIter1 and InputIter2 are
// both random-access iterators, and `last1` - `first1` != `last2` - `first2`,
// then the predicate is never invoked and the function returns false.
//
// This is a C++11-compatible implementation of C++14 `std::equal`. See
// https://en.cppreference.com/w/cpp/algorithm/equal for more information.
template <typename InputIter1, typename InputIter2, typename Pred>
bool equal(InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
InputIter2 last2,
Pred&& pred) {
return internal::EqualImpl(
first1,
last1,
first2,
last2,
std::forward<Pred>(pred),
typename std::iterator_traits<InputIter1>::iterator_category{},
typename std::iterator_traits<InputIter2>::iterator_category{});
}
// Performs comparison of two ranges specified by pairs of iterators using
// operator==.
template <typename InputIter1, typename InputIter2>
bool equal(InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
InputIter2 last2) {
return internal::equal(first1, last1, first2, last2, internal::EqualTo{});
}
} // namespace internal
} // namespace ceres
#endif // CERES_PUBLIC_INTERNAL_ALGORITHM_H_
+7 -6
View File
@@ -143,6 +143,7 @@
#include <stddef.h>
#include <array>
#include <utility>
#include "ceres/internal/array_selector.h"
#include "ceres/internal/eigen.h"
@@ -213,14 +214,14 @@ template <typename Seq, int ParameterIdx = 0, int Offset = 0>
struct Make1stOrderPerturbations;
template <int N, int... Ns, int ParameterIdx, int Offset>
struct Make1stOrderPerturbations<integer_sequence<int, N, Ns...>,
struct Make1stOrderPerturbations<std::integer_sequence<int, N, Ns...>,
ParameterIdx,
Offset> {
template <typename T, typename JetT>
inline static void Apply(T const* const* parameters, JetT* x) {
Make1stOrderPerturbation<0, N, Offset, T, JetT>::Apply(
parameters[ParameterIdx], x + Offset);
Make1stOrderPerturbations<integer_sequence<int, Ns...>,
Make1stOrderPerturbations<std::integer_sequence<int, Ns...>,
ParameterIdx + 1,
Offset + N>::Apply(parameters, x);
}
@@ -228,7 +229,7 @@ struct Make1stOrderPerturbations<integer_sequence<int, N, Ns...>,
// End of 'recursion'. Nothing more to do.
template <int ParameterIdx, int Total>
struct Make1stOrderPerturbations<integer_sequence<int>, ParameterIdx, Total> {
struct Make1stOrderPerturbations<std::integer_sequence<int>, ParameterIdx, Total> {
template <typename T, typename JetT>
static void Apply(T const* const* /* NOT USED */, JetT* /* NOT USED */) {}
};
@@ -276,7 +277,7 @@ template <typename Seq, int ParameterIdx = 0, int Offset = 0>
struct Take1stOrderParts;
template <int N, int... Ns, int ParameterIdx, int Offset>
struct Take1stOrderParts<integer_sequence<int, N, Ns...>,
struct Take1stOrderParts<std::integer_sequence<int, N, Ns...>,
ParameterIdx,
Offset> {
template <typename JetT, typename T>
@@ -284,7 +285,7 @@ struct Take1stOrderParts<integer_sequence<int, N, Ns...>,
if (jacobians[ParameterIdx]) {
Take1stOrderPart<Offset, N>(num_outputs, output, jacobians[ParameterIdx]);
}
Take1stOrderParts<integer_sequence<int, Ns...>,
Take1stOrderParts<std::integer_sequence<int, Ns...>,
ParameterIdx + 1,
Offset + N>::Apply(num_outputs, output, jacobians);
}
@@ -292,7 +293,7 @@ struct Take1stOrderParts<integer_sequence<int, N, Ns...>,
// End of 'recursion'. Nothing more to do.
template <int ParameterIdx, int Offset>
struct Take1stOrderParts<integer_sequence<int>, ParameterIdx, Offset> {
struct Take1stOrderParts<std::integer_sequence<int>, ParameterIdx, Offset> {
template <typename T, typename JetT>
static void Apply(int /* NOT USED*/,
JetT* /* NOT USED*/,
+1 -2
View File
@@ -39,7 +39,6 @@
#include <Eigen/Core> // For Eigen::aligned_allocator
#include "ceres/internal/algorithm.h"
#include "ceres/internal/memory.h"
#include "glog/logging.h"
@@ -312,7 +311,7 @@ class FixedArray {
// Relational operators. Equality operators are elementwise using
// `operator==`, while order operators order FixedArrays lexicographically.
friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) {
return internal::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) {
-106
View File
@@ -1,106 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2018 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: jodebo_beck@gmx.de (Johannes Beck)
//
// This class mimics std::integer_sequence. That is the reason to follow the
// naming convention of the stl and not the google one. Once Ceres switches
// to c++ 14 this class can be removed.
#ifndef CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_H_
#define CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_H_
#if __cplusplus >= 201402L
// We have at least c++ 14 support. Use integer_sequence from the standard.
// Sometimes the STL implementation uses a compiler intrinsic to generate
// the sequences which will speed up compilation.
#include <utility>
namespace ceres {
namespace internal {
template <typename T, T... Ns>
using integer_sequence = std::integer_sequence<T, Ns...>;
template <typename T, T N>
using make_integer_sequence = std::make_integer_sequence<T, N>;
} // namespace internal
} // namespace ceres
#else
namespace ceres {
namespace internal {
template <typename T, T... Ns>
struct integer_sequence {
using value_type = T;
};
// Implementation of make_integer_sequence.
//
// Recursively instantiate make_integer_sequence_impl until Ns
// contains the sequence 0, 1, ..., Total-1.
//
// Example for Total = 4:
// T CurIdx, Total, Ns...
// make_integer_sequence_impl<int, 0, 4 >
// make_integer_sequence_impl<int, 1, 4, 0 >
// make_integer_sequence_impl<int, 2, 4, 0, 1 >
// make_integer_sequence_impl<int, 3, 4, 0, 1, 2 >
// make_integer_sequence_impl<int, 4, 4, 0, 1, 2, 3>
// ^^^^^^^^^^
// resulting sequence.
//
// The implemented algorithm has linear complexity for simplicity. A O(log(N))
// implementation can be found e.g. here:
// https://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence
template <typename T, T CurIdx, T Total, T... Ns>
struct make_integer_sequence_impl {
using type = typename make_integer_sequence_impl<T, CurIdx + 1, Total, Ns...,
CurIdx>::type;
};
// End of 'recursion' when CurIdx reaches Total. All indices 0, 1, ..., N-1 are
// contained in Ns. The final integer_sequence is created here.
template <typename T, T Total, T... Ns>
struct make_integer_sequence_impl<T, Total, Total, Ns...> {
using type = integer_sequence<T, Ns...>;
};
// A helper alias template to simplify creation of integer_sequence with 0, 1,
// ..., N-1 as Ns:
template <typename T, T N>
using make_integer_sequence =
typename make_integer_sequence_impl<T, 0, N>::type;
} // namespace internal
} // namespace ceres
#endif
#endif // CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_H_
@@ -35,7 +35,7 @@
#ifndef CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
#define CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
#include "integer_sequence.h"
#include <utility>
namespace ceres {
namespace internal {
@@ -61,33 +61,33 @@ struct SumImpl;
// Strip of and sum the first number.
template <typename T, T N, T... Ns>
struct SumImpl<integer_sequence<T, N, Ns...>> {
static constexpr T Value = N + SumImpl<integer_sequence<T, Ns...>>::Value;
struct SumImpl<std::integer_sequence<T, N, Ns...>> {
static constexpr T Value = N + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Strip of and sum the first two numbers.
template <typename T, T N1, T N2, T... Ns>
struct SumImpl<integer_sequence<T, N1, N2, Ns...>> {
struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
static constexpr T Value =
N1 + N2 + SumImpl<integer_sequence<T, Ns...>>::Value;
N1 + N2 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Strip of and sum the first four numbers.
template <typename T, T N1, T N2, T N3, T N4, T... Ns>
struct SumImpl<integer_sequence<T, N1, N2, N3, N4, Ns...>> {
struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
static constexpr T Value =
N1 + N2 + N3 + N4 + SumImpl<integer_sequence<T, Ns...>>::Value;
N1 + N2 + N3 + N4 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Only one number is left. 'Value' is just that number ('recursion' ends).
template <typename T, T N>
struct SumImpl<integer_sequence<T, N>> {
struct SumImpl<std::integer_sequence<T, N>> {
static constexpr T Value = N;
};
// No number is left. 'Value' is the identity element (for sum this is zero).
template <typename T>
struct SumImpl<integer_sequence<T>> {
struct SumImpl<std::integer_sequence<T>> {
static constexpr T Value = T(0);
};
@@ -129,16 +129,16 @@ template <typename T, T Sum, typename SeqIn, typename SeqOut>
struct ExclusiveScanImpl;
template <typename T, T Sum, T N, T... Ns, T... Rs>
struct ExclusiveScanImpl<T, Sum, integer_sequence<T, N, Ns...>,
integer_sequence<T, Rs...>> {
struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T, N, Ns...>,
std::integer_sequence<T, Rs...>> {
using Type =
typename ExclusiveScanImpl<T, Sum + N, integer_sequence<T, Ns...>,
integer_sequence<T, Rs..., Sum>>::Type;
typename ExclusiveScanImpl<T, Sum + N, std::integer_sequence<T, Ns...>,
std::integer_sequence<T, Rs..., Sum>>::Type;
};
// End of 'recursion'. The resulting type is SeqOut.
template <typename T, T Sum, typename SeqOut>
struct ExclusiveScanImpl<T, Sum, integer_sequence<T>, SeqOut> {
struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
using Type = SeqOut;
};
@@ -152,7 +152,7 @@ class ExclusiveScanT {
public:
using Type =
typename ExclusiveScanImpl<T, T(0), Seq, integer_sequence<T>>::Type;
typename ExclusiveScanImpl<T, T(0), Seq, std::integer_sequence<T>>::Type;
};
// Helper to use exclusive scan without typename.
+4 -3
View File
@@ -36,6 +36,7 @@
#define CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
#include <cstring>
#include <utility>
#include "Eigen/Dense"
#include "Eigen/StdVector"
@@ -437,7 +438,7 @@ struct EvaluateJacobianForParameterBlocks;
template <typename ParameterDims, int N, int... Ns, int ParameterIdx>
struct EvaluateJacobianForParameterBlocks<ParameterDims,
integer_sequence<int, N, Ns...>,
std::integer_sequence<int, N, Ns...>,
ParameterIdx> {
template <NumericDiffMethodType method,
int kNumResiduals,
@@ -468,7 +469,7 @@ struct EvaluateJacobianForParameterBlocks<ParameterDims,
}
return EvaluateJacobianForParameterBlocks<ParameterDims,
integer_sequence<int, Ns...>,
std::integer_sequence<int, Ns...>,
ParameterIdx + 1>::
template Apply<method, kNumResiduals>(functor,
residuals_at_eval_point,
@@ -481,7 +482,7 @@ struct EvaluateJacobianForParameterBlocks<ParameterDims,
// End of 'recursion'. Nothing more to do.
template <typename ParameterDims, int ParameterIdx>
struct EvaluateJacobianForParameterBlocks<ParameterDims, integer_sequence<int>,
struct EvaluateJacobianForParameterBlocks<ParameterDims, std::integer_sequence<int>,
ParameterIdx> {
template <NumericDiffMethodType method, int kNumResiduals,
typename CostFunctor>
+7 -7
View File
@@ -32,8 +32,8 @@
#define CERES_PUBLIC_INTERNAL_PARAMETER_DIMS_H_
#include <array>
#include <utility>
#include "ceres/internal/integer_sequence.h"
#include "ceres/internal/integer_sequence_algorithm.h"
namespace ceres {
@@ -41,16 +41,16 @@ namespace internal {
// Checks, whether the given parameter block sizes are valid. Valid means every
// dimension is bigger than zero.
constexpr bool IsValidParameterDimensionSequence(integer_sequence<int>) {
constexpr bool IsValidParameterDimensionSequence(std::integer_sequence<int>) {
return true;
}
template <int N, int... Ts>
constexpr bool IsValidParameterDimensionSequence(
integer_sequence<int, N, Ts...>) {
std::integer_sequence<int, N, Ts...>) {
return (N <= 0) ? false
: IsValidParameterDimensionSequence(
integer_sequence<int, Ts...>());
std::integer_sequence<int, Ts...>());
}
// Helper class that represents the parameter dimensions. The parameter
@@ -66,7 +66,7 @@ constexpr bool IsValidParameterDimensionSequence(
template <bool IsDynamic, int... Ns>
class ParameterDims {
public:
using Parameters = integer_sequence<int, Ns...>;
using Parameters = std::integer_sequence<int, Ns...>;
// The parameter dimensions are only valid if all parameter block dimensions
// are greater than zero.
@@ -82,7 +82,7 @@ class ParameterDims {
"At least one parameter block must be specified.");
static constexpr int kNumParameters =
Sum<integer_sequence<int, Ns...>>::Value;
Sum<std::integer_sequence<int, Ns...>>::Value;
static constexpr int GetDim(int dim) { return params_[dim]; }
@@ -98,7 +98,7 @@ class ParameterDims {
private:
template <typename T, int... Indices>
static inline std::array<T*, kNumParameterBlocks> GetUnpackedParameters(
T* ptr, integer_sequence<int, Indices...>) {
T* ptr, std::integer_sequence<int, Indices...>) {
return std::array<T*, kNumParameterBlocks>{{ptr + Indices...}};
}
+7 -7
View File
@@ -35,19 +35,19 @@
#include "ceres/internal/config.h"
#if defined(CERES_USE_OPENMP)
# if defined(CERES_USE_CXX11_THREADS) || defined(CERES_NO_THREADS)
# error CERES_USE_OPENMP is mutually exclusive to CERES_USE_CXX11_THREADS and CERES_NO_THREADS
# if defined(CERES_USE_CXX_THREADS) || defined(CERES_NO_THREADS)
# error CERES_USE_OPENMP is mutually exclusive to CERES_USE_CXX_THREADS and CERES_NO_THREADS
# endif
#elif defined(CERES_USE_CXX11_THREADS)
#elif defined(CERES_USE_CXX_THREADS)
# if defined(CERES_USE_OPENMP) || defined(CERES_NO_THREADS)
# error CERES_USE_CXX11_THREADS is mutually exclusive to CERES_USE_OPENMP, CERES_USE_CXX11_THREADS and CERES_NO_THREADS
# error CERES_USE_CXX_THREADS is mutually exclusive to CERES_USE_OPENMP, CERES_USE_CXX_THREADS and CERES_NO_THREADS
# endif
#elif defined(CERES_NO_THREADS)
# if defined(CERES_USE_OPENMP) || defined(CERES_USE_CXX11_THREADS)
# error CERES_NO_THREADS is mutually exclusive to CERES_USE_OPENMP and CERES_USE_CXX11_THREADS
# if defined(CERES_USE_OPENMP) || defined(CERES_USE_CXX_THREADS)
# error CERES_NO_THREADS is mutually exclusive to CERES_USE_OPENMP and CERES_USE_CXX_THREADS
# endif
#else
# error One of CERES_USE_OPENMP, CERES_USE_CXX11_THREADS or CERES_NO_THREADS must be defined.
# error One of CERES_USE_OPENMP, CERES_USE_CXX_THREADS or CERES_NO_THREADS must be defined.
#endif
// CERES_NO_SPARSE should be automatically defined by config.h if Ceres was
+4 -3
View File
@@ -36,6 +36,7 @@
#include <stddef.h>
#include <type_traits>
#include <utility>
#include "ceres/cost_function.h"
#include "ceres/internal/parameter_dims.h"
@@ -47,7 +48,7 @@ namespace internal {
template <typename Functor, typename T, int... Indices>
inline bool VariadicEvaluateImpl(const Functor& functor, T const* const* input,
T* output, std::false_type /*is_dynamic*/,
integer_sequence<int, Indices...>) {
std::integer_sequence<int, Indices...>) {
static_assert(sizeof...(Indices),
"Invalid number of parameter blocks. At least one parameter "
"block must be specified.");
@@ -58,7 +59,7 @@ inline bool VariadicEvaluateImpl(const Functor& functor, T const* const* input,
template <typename Functor, typename T>
inline bool VariadicEvaluateImpl(const Functor& functor, T const* const* input,
T* output, std::true_type /*is_dynamic*/,
integer_sequence<int>) {
std::integer_sequence<int>) {
return functor(input, output);
}
@@ -67,7 +68,7 @@ template <typename ParameterDims, typename Functor, typename T>
inline bool VariadicEvaluateImpl(const Functor& functor, T const* const* input,
T* output, const void* /* NOT USED */) {
using ParameterBlockIndices =
make_integer_sequence<int, ParameterDims::kNumParameterBlocks>;
std::make_integer_sequence<int, ParameterDims::kNumParameterBlocks>;
using IsDynamic = std::integral_constant<bool, ParameterDims::kIsDynamic>;
return VariadicEvaluateImpl(functor, input, output, IsDynamic(),
ParameterBlockIndices());
+1 -3
View File
@@ -30,7 +30,7 @@
# Avoid 'xxx.cc has no symbols' warnings from source files which are 'empty'
# when their enclosing #ifdefs are disabled.
if (CERES_THREADING_MODEL STREQUAL "CXX11_THREADS")
if (CERES_THREADING_MODEL STREQUAL "CXX_THREADS")
set(CERES_PARALLEL_FOR_SRC parallel_for_cxx.cc thread_pool.cc)
elseif (CERES_THREADING_MODEL STREQUAL "OPENMP")
set(CERES_PARALLEL_FOR_SRC parallel_for_openmp.cc)
@@ -397,7 +397,6 @@ if (BUILD_TESTING AND GFLAGS)
${Ceres_SOURCE_DIR}/data)
endmacro (CERES_TEST)
ceres_test(algorithm)
ceres_test(array_utils)
ceres_test(array_selector)
ceres_test(autodiff)
@@ -442,7 +441,6 @@ if (BUILD_TESTING AND GFLAGS)
ceres_test(implicit_schur_complement)
ceres_test(inner_product_computer)
ceres_test(invert_psd_matrix)
ceres_test(integer_sequence)
ceres_test(integer_sequence_algorithm)
ceres_test(is_close)
ceres_test(iterative_refiner)
-173
View File
@@ -1,173 +0,0 @@
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ceres/internal/algorithm.h"
#include <algorithm>
#include <list>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace {
TEST(EqualTest, DefaultComparisonRandomAccess) {
std::vector<int> v1{1, 2, 3};
std::vector<int> v2 = v1;
std::vector<int> v3 = {1, 2};
std::vector<int> v4 = {1, 2, 4};
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), v2.begin(), v2.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v3.begin(), v3.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v4.begin(), v4.end()));
}
TEST(EqualTest, DefaultComparison) {
std::list<int> lst1{1, 2, 3};
std::list<int> lst2 = lst1;
std::list<int> lst3{1, 2};
std::list<int> lst4{1, 2, 4};
EXPECT_TRUE(ceres::internal::equal(
lst1.begin(), lst1.end(), lst2.begin(), lst2.end()));
EXPECT_FALSE(ceres::internal::equal(
lst1.begin(), lst1.end(), lst3.begin(), lst3.end()));
EXPECT_FALSE(ceres::internal::equal(
lst1.begin(), lst1.end(), lst4.begin(), lst4.end()));
}
TEST(EqualTest, EmptyRange) {
std::vector<int> v1{1, 2, 3};
std::vector<int> empty1;
std::vector<int> empty2;
EXPECT_FALSE(ceres::internal::equal(
v1.begin(), v1.end(), empty1.begin(), empty1.end()));
EXPECT_FALSE(ceres::internal::equal(
empty1.begin(), empty1.end(), v1.begin(), v1.end()));
EXPECT_TRUE(ceres::internal::equal(
empty1.begin(), empty1.end(), empty2.begin(), empty2.end()));
}
TEST(EqualTest, MixedIterTypes) {
std::vector<int> v1{1, 2, 3};
std::list<int> lst1{v1.begin(), v1.end()};
std::list<int> lst2{1, 2, 4};
std::list<int> lst3{1, 2};
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), lst1.begin(), lst1.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), lst2.begin(), lst2.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), lst3.begin(), lst3.end()));
}
TEST(EqualTest, MixedValueTypes) {
std::vector<int> v1{1, 2, 3};
std::vector<char> v2{1, 2, 3};
std::vector<char> v3{1, 2};
std::vector<char> v4{1, 2, 4};
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), v2.begin(), v2.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v3.begin(), v3.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v4.begin(), v4.end()));
}
TEST(EqualTest, WeirdIterators) {
std::vector<bool> v1{true, false};
std::vector<bool> v2 = v1;
std::vector<bool> v3{true};
std::vector<bool> v4{true, true, true};
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), v2.begin(), v2.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v3.begin(), v3.end()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v4.begin(), v4.end()));
}
TEST(EqualTest, CustomComparison) {
int n[] = {1, 2, 3, 4};
std::vector<int*> v1{&n[0], &n[1], &n[2]};
std::vector<int*> v2 = v1;
std::vector<int*> v3{&n[0], &n[1], &n[3]};
std::vector<int*> v4{&n[0], &n[1]};
auto eq = [](int* a, int* b) { return *a == *b; };
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), eq));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), eq));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v4.begin(), v4.end(), eq));
}
TEST(EqualTest, MoveOnlyPredicate) {
std::vector<int> v1{1, 2, 3};
std::vector<int> v2{4, 5, 6};
// move-only equality predicate
struct Eq {
Eq() = default;
Eq(Eq&&) = default;
Eq(const Eq&) = delete;
Eq& operator=(const Eq&) = delete;
bool operator()(const int a, const int b) const { return a == b; }
};
EXPECT_TRUE(
ceres::internal::equal(v1.begin(), v1.end(), v1.begin(), v1.end(), Eq()));
EXPECT_FALSE(
ceres::internal::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), Eq()));
}
struct CountingTrivialPred {
int* count;
bool operator()(int, int) const {
++*count;
return true;
}
};
TEST(EqualTest, RandomAccessComplexity) {
std::vector<int> v1{1, 1, 3};
std::vector<int> v2 = v1;
std::vector<int> v3{1, 2};
do {
int count = 0;
ceres::internal::equal(v1.begin(),
v1.end(),
v2.begin(),
v2.end(),
CountingTrivialPred{&count});
EXPECT_LE(count, 3);
} while (std::next_permutation(v2.begin(), v2.end()));
int count = 0;
ceres::internal::equal(
v1.begin(), v1.end(), v3.begin(), v3.end(), CountingTrivialPred{&count});
EXPECT_EQ(count, 0);
}
} // namespace
+2 -2
View File
@@ -31,7 +31,7 @@
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include <chrono>
#include <thread>
@@ -304,4 +304,4 @@ TEST(ConcurrentQueue, StopAndEnableWaiters) {
} // namespace internal
} // namespace ceres
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
+2 -2
View File
@@ -34,9 +34,9 @@ namespace ceres {
namespace internal {
void ContextImpl::EnsureMinimumThreads(int num_threads) {
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
thread_pool.Resize(num_threads);
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
}
} // namespace internal
+5 -5
View File
@@ -36,9 +36,9 @@
#include "ceres/context.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include "ceres/thread_pool.h"
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
namespace ceres {
namespace internal {
@@ -51,14 +51,14 @@ class ContextImpl : public Context {
virtual ~ContextImpl() {}
// When compiled with C++11 threading support, resize the thread pool to have
// When compiled with C++ threading support, resize the thread pool to have
// at min(num_thread, num_hardware_threads) where num_hardware_threads is
// defined by the hardware. Otherwise this call is a no-op.
void EnsureMinimumThreads(int num_threads);
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
ThreadPool thread_pool;
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
};
} // namespace internal
@@ -31,39 +31,40 @@
#include "ceres/internal/integer_sequence_algorithm.h"
#include <type_traits>
#include <utility>
namespace ceres {
namespace internal {
// Unit tests for summation of integer sequence.
static_assert(Sum<integer_sequence<int>>::Value == 0,
static_assert(Sum<std::integer_sequence<int>>::Value == 0,
"Unit test of summing up an integer sequence failed.");
static_assert(Sum<integer_sequence<int, 2>>::Value == 2,
static_assert(Sum<std::integer_sequence<int, 2>>::Value == 2,
"Unit test of summing up an integer sequence failed.");
static_assert(Sum<integer_sequence<int, 2, 3>>::Value == 5,
static_assert(Sum<std::integer_sequence<int, 2, 3>>::Value == 5,
"Unit test of summing up an integer sequence failed.");
static_assert(Sum<integer_sequence<int, 2, 3, 10>>::Value == 15,
static_assert(Sum<std::integer_sequence<int, 2, 3, 10>>::Value == 15,
"Unit test of summing up an integer sequence failed.");
static_assert(Sum<integer_sequence<int, 2, 3, 10, 4>>::Value == 19,
static_assert(Sum<std::integer_sequence<int, 2, 3, 10, 4>>::Value == 19,
"Unit test of summing up an integer sequence failed.");
static_assert(Sum<integer_sequence<int, 2, 3, 10, 4, 1>>::Value == 20,
static_assert(Sum<std::integer_sequence<int, 2, 3, 10, 4, 1>>::Value == 20,
"Unit test of summing up an integer sequence failed.");
// Unit tests for exclusive scan of integer sequence.
static_assert(std::is_same<ExclusiveScan<integer_sequence<int>>,
integer_sequence<int>>::value,
static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int>>,
std::integer_sequence<int>>::value,
"Unit test of calculating the exclusive scan of an integer "
"sequence failed.");
static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2>>,
integer_sequence<int, 0>>::value,
static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2>>,
std::integer_sequence<int, 0>>::value,
"Unit test of calculating the exclusive scan of an integer "
"sequence failed.");
static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2, 1>>,
integer_sequence<int, 0, 2>>::value,
static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2, 1>>,
std::integer_sequence<int, 0, 2>>::value,
"Unit test of calculating the exclusive scan of an integer "
"sequence failed.");
static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2, 1, 10>>,
integer_sequence<int, 0, 2, 3>>::value,
static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2, 1, 10>>,
std::integer_sequence<int, 0, 2, 3>>::value,
"Unit test of calculating the exclusive scan of an integer "
"sequence failed.");
-58
View File
@@ -1,58 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2018 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: jodebo_beck@gmx.de (Johannes Beck)
#include "ceres/internal/integer_sequence.h"
#include <type_traits>
namespace ceres {
namespace internal {
// Unit test for integer_sequence<...>::value_type
static_assert(std::is_same<integer_sequence<unsigned int, 0>::value_type,
unsigned int>::value,
"Unit test of integer sequence value type failed.");
// Unit tests for make_integer_sequence
static_assert(
std::is_same<make_integer_sequence<int, 0>, integer_sequence<int>>::value,
"Unit test of make integer sequence failed.");
static_assert(std::is_same<make_integer_sequence<int, 1>,
integer_sequence<int, 0>>::value,
"Unit test of make integer sequence failed.");
static_assert(std::is_same<make_integer_sequence<int, 2>,
integer_sequence<int, 0, 1>>::value,
"Unit test of make integer sequence failed.");
static_assert(std::is_same<make_integer_sequence<int, 3>,
integer_sequence<int, 0, 1, 2>>::value,
"Unit test of make integer sequence failed.");
} // namespace internal
} // namespace ceres
+2 -2
View File
@@ -31,7 +31,7 @@
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include "ceres/parallel_for.h"
@@ -244,4 +244,4 @@ void ParallelFor(ContextImpl* context,
} // namespace internal
} // namespace ceres
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
+6 -5
View File
@@ -26,28 +26,29 @@
#include <gtest/gtest.h>
#include <type_traits>
#include <utility>
namespace ceres {
namespace internal {
// Is valid parameter dims unit test
static_assert(IsValidParameterDimensionSequence(integer_sequence<int>()) ==
static_assert(IsValidParameterDimensionSequence(std::integer_sequence<int>()) ==
true,
"Unit test of is valid parameter dimension sequence failed.");
static_assert(
IsValidParameterDimensionSequence(integer_sequence<int, 2, 1>()) == true,
IsValidParameterDimensionSequence(std::integer_sequence<int, 2, 1>()) == true,
"Unit test of is valid parameter dimension sequence failed.");
static_assert(
IsValidParameterDimensionSequence(integer_sequence<int, 0, 1>()) == false,
IsValidParameterDimensionSequence(std::integer_sequence<int, 0, 1>()) == false,
"Unit test of is valid parameter dimension sequence failed.");
static_assert(
IsValidParameterDimensionSequence(integer_sequence<int, 3, 0>()) == false,
IsValidParameterDimensionSequence(std::integer_sequence<int, 3, 0>()) == false,
"Unit test of is valid parameter dimension sequence failed.");
// Static parameter dims unit test
static_assert(
std::is_same<StaticParameterDims<4, 2, 1>::Parameters,
integer_sequence<int, 4, 2, 1>>::value == true,
std::integer_sequence<int, 4, 2, 1>>::value == true,
"Unit test of type 'parameters' for static parameter dims failed.");
static_assert(StaticParameterDims<4, 2, 1>::kIsValid == true,
+1 -1
View File
@@ -43,7 +43,7 @@
// residual jacobians are written directly into their final position in the
// block sparse matrix by the user's CostFunction; there is no copying.
//
// The evaluation is threaded with OpenMP or C++11 threads.
// The evaluation is threaded with OpenMP or C++ threads.
//
// The EvaluatePreparer and JacobianWriter interfaces are as follows:
//
+2 -1
View File
@@ -33,6 +33,7 @@
#include <cmath>
#include <limits>
#include <memory>
#include <utility>
#include <vector>
#include "ceres/internal/integer_sequence_algorithm.h"
@@ -69,7 +70,7 @@ class MockCostFunctionBase : public SizedCostFunction<kNumResiduals, Ns...> {
bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const final {
const int kNumParameters = Sum<integer_sequence<int, Ns...>>::Value;
const int kNumParameters = Sum<std::integer_sequence<int, Ns...>>::Value;
for (int i = 0; i < kNumResiduals; ++i) {
residuals[i] = kNumResiduals + kNumParameters;
-22
View File
@@ -43,28 +43,6 @@ namespace internal {
using std::string;
// va_copy() was defined in the C99 standard. However, it did not appear in the
// C++ standard until C++11. This means that if Ceres is being compiled with a
// strict pre-C++11 standard (e.g. -std=c++03), va_copy() will NOT be defined,
// as we are using the C++ compiler (it would however be defined if we were
// using the C compiler). Note however that both GCC & Clang will in fact
// define va_copy() when compiling for C++ if the C++ standard is not explicitly
// specified (i.e. no -std=c++<XX> arg), even though it should not strictly be
// defined unless -std=c++11 (or greater) was passed.
#if !defined(va_copy)
#if defined (__GNUC__)
// On GCC/Clang, if va_copy() is not defined (C++ standard < C++11 explicitly
// specified), use the internal __va_copy() version, which should be present
// in even very old GCC versions.
#define va_copy(d, s) __va_copy(d, s)
#else
// Some older versions of MSVC do not have va_copy(), in which case define it.
// Although this is required for older MSVC versions, it should also work for
// other non-GCC/Clang compilers which also do not defined va_copy().
#define va_copy(d, s) ((d) = (s))
#endif // defined (__GNUC__)
#endif // !defined(va_copy)
void StringAppendV(string* dst, const char* format, va_list ap) {
// First try with a small fixed size buffer
char space[1024];
+2 -2
View File
@@ -31,7 +31,7 @@
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include "ceres/thread_pool.h"
@@ -113,4 +113,4 @@ void ThreadPool::Stop() {
} // namespace internal
} // namespace ceres
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
+2 -2
View File
@@ -31,7 +31,7 @@
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include "ceres/thread_pool.h"
@@ -197,4 +197,4 @@ TEST(ThreadPool, Resize) {
} // namespace internal
} // namespace ceres
#endif // CERES_USE_CXX11_THREADS
#endif // CERES_USE_CXX_THREADS
+3 -3
View File
@@ -39,7 +39,7 @@ namespace internal {
ThreadTokenProvider::ThreadTokenProvider(int num_threads) {
(void)num_threads;
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
for (int i = 0; i < num_threads; i++) {
pool_.Push(i);
}
@@ -56,7 +56,7 @@ int ThreadTokenProvider::Acquire() {
return 0;
#endif
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
int thread_id;
CHECK(pool_.Wait(&thread_id));
return thread_id;
@@ -66,7 +66,7 @@ int ThreadTokenProvider::Acquire() {
void ThreadTokenProvider::Release(int thread_id) {
(void)thread_id;
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
pool_.Push(thread_id);
#endif
+4 -4
View File
@@ -34,15 +34,15 @@
#include "ceres/internal/config.h"
#include "ceres/internal/port.h"
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
#include "ceres/concurrent_queue.h"
#endif
namespace ceres {
namespace internal {
// Helper for C++11 thread number identification that is similar to
// omp_get_thread_num() behaviour. This is necessary to support C++11
// Helper for C++ thread number identification that is similar to
// omp_get_thread_num() behaviour. This is necessary to support C++
// threading with a sequential thread id. This is used to access preallocated
// resources in the parallelized code parts. The sequence of tokens varies from
// 0 to num_threads - 1 that can be acquired to identify the thread in a thread
@@ -78,7 +78,7 @@ class ThreadTokenProvider {
void Release(int thread_id);
private:
#ifdef CERES_USE_CXX11_THREADS
#ifdef CERES_USE_CXX_THREADS
// This queue initially holds a sequence from 0..num_threads-1. Every
// Acquire() call the first number is removed from here. When the token is not
// needed anymore it shall be given back with corresponding Release()