diff --git a/include/ceres/codegen/internal/expression_ref.h b/include/ceres/codegen/internal/expression_ref.h index d73d477dc..5499930e1 100644 --- a/include/ceres/codegen/internal/expression_ref.h +++ b/include/ceres/codegen/internal/expression_ref.h @@ -46,7 +46,7 @@ namespace internal { // // ExpressionRef should be passed by value. struct ExpressionRef { - ExpressionRef() = default; + ExpressionRef() : ExpressionRef(0.0) {} // Create a compile time constant expression directly from a double value. // This is important so that we can write T(3.14) in our code and @@ -57,6 +57,10 @@ struct ExpressionRef { // must work for T = Jet. ExpressionRef(double compile_time_constant); + // Adds the expression to the active graph and initializes this ExpressionRef + // accordingly. + ExpressionRef(const Expression& expression); + // By adding this deleted constructor we can detect invalid usage of // ExpressionRef. ExpressionRef must only be created from constexpr doubles. // @@ -97,8 +101,6 @@ struct ExpressionRef { // The index into the ExpressionGraph data array. ExpressionId id = kInvalidExpressionId; - - static ExpressionRef Create(ExpressionId id); }; // A helper function which calls 'InsertBack' on the currently active graph. diff --git a/internal/ceres/codegen/code_generator_test.cc b/internal/ceres/codegen/code_generator_test.cc index 8b4aafc4b..f799a7591 100644 --- a/internal/ceres/codegen/code_generator_test.cc +++ b/internal/ceres/codegen/code_generator_test.cc @@ -46,7 +46,7 @@ static void GenerateAndCheck(const ExpressionGraph& graph, auto code = gen.Generate(); EXPECT_EQ(code.size(), reference.size()); - for (int i = 0; i < code.size(); ++i) { + for (int i = 0; i < std::min(code.size(), reference.size()); ++i) { EXPECT_EQ(code[i], reference[i]) << "Invalid Line: " << (i + 1); } } @@ -69,7 +69,7 @@ TEST(CodeGenerator, COMPILE_TIME_CONSTANT) { T d = T(std::numeric_limits::infinity()); T e = T(-std::numeric_limits::infinity()); T f = T(std::numeric_limits::quiet_NaN()); - T g; // Uninitialized variables should not generate code! + T g; // Uninitialized variables are 0 initialized. auto graph = StopRecordingExpressions(); std::vector expected_code = { "{", @@ -79,12 +79,14 @@ TEST(CodeGenerator, COMPILE_TIME_CONSTANT) { " double v_3;", " double v_4;", " double v_5;", + " double v_6;", " v_0 = 0;", " v_1 = 123.5;", " v_2 = 2;", " v_3 = std::numeric_limits::infinity();", " v_4 = -std::numeric_limits::infinity();", " v_5 = std::numeric_limits::quiet_NaN();", + " v_6 = 0;", "}"}; GenerateAndCheck(graph, expected_code); } diff --git a/internal/ceres/codegen/expression_ref.cc b/internal/ceres/codegen/expression_ref.cc index 883d4ea72..369aec445 100644 --- a/internal/ceres/codegen/expression_ref.cc +++ b/internal/ceres/codegen/expression_ref.cc @@ -37,23 +37,19 @@ namespace ceres { namespace internal { ExpressionRef AddExpressionToGraph(const Expression& expression) { + return ExpressionRef(expression); +} + +ExpressionRef::ExpressionRef(double compile_time_constant) + : ExpressionRef( + Expression::CreateCompileTimeConstant(compile_time_constant)) {} + +ExpressionRef::ExpressionRef(const Expression& expression) { ExpressionGraph* graph = GetCurrentExpressionGraph(); CHECK(graph) << "The ExpressionGraph has to be created before using Expressions. This " "is achieved by calling ceres::StartRecordingExpressions."; - return ExpressionRef::Create(graph->InsertBack(expression)); -} - -ExpressionRef ExpressionRef::Create(ExpressionId id) { - ExpressionRef ref; - ref.id = id; - return ref; -} - -ExpressionRef::ExpressionRef(double compile_time_constant) { - id = AddExpressionToGraph( - Expression::CreateCompileTimeConstant(compile_time_constant)) - .id; + id = graph->InsertBack(expression); } ExpressionRef::ExpressionRef(const ExpressionRef& other) { *this = other; } diff --git a/internal/ceres/codegen/expression_ref_test.cc b/internal/ceres/codegen/expression_ref_test.cc index 280043b88..c9a118be1 100644 --- a/internal/ceres/codegen/expression_ref_test.cc +++ b/internal/ceres/codegen/expression_ref_test.cc @@ -48,13 +48,14 @@ TEST(ExpressionRef, COMPILE_TIME_CONSTANT) { T a = T(0); T b = T(123.5); T c = T(1 + 1); - T d; // Uninitialized variables should not generate code! + T d; // Uninitialized variables are also compile time constants auto graph = StopRecordingExpressions(); ExpressionGraph reference; reference.InsertBack(Expression::CreateCompileTimeConstant(0)); reference.InsertBack(Expression::CreateCompileTimeConstant(123.5)); reference.InsertBack(Expression::CreateCompileTimeConstant(2)); + reference.InsertBack(Expression::CreateCompileTimeConstant(0)); EXPECT_EQ(reference, graph); }