diff --git a/rclcpp/include/rclcpp/duration.hpp b/rclcpp/include/rclcpp/duration.hpp index 49125ec722..e5d7c5e130 100644 --- a/rclcpp/include/rclcpp/duration.hpp +++ b/rclcpp/include/rclcpp/duration.hpp @@ -38,10 +38,14 @@ class RCLCPP_PUBLIC Duration */ Duration(int32_t seconds, uint32_t nanoseconds); - // This constructor matches any numeric value - ints or floats. + /// Construct duration from the specified nanoseconds. + [[deprecated( + "Use Duration::from_nanoseconds instead or std::chrono_literals. For example:" + "rclcpp::Duration::from_nanoseconds(int64_variable);" + "rclcpp::Duration(0ns);")]] explicit Duration(rcl_duration_value_t nanoseconds); - // This constructor matches std::chrono::nanoseconds. + /// Construct duration from the specified std::chrono::nanoseconds. explicit Duration(std::chrono::nanoseconds nanoseconds); // This constructor matches any std::chrono value other than nanoseconds @@ -129,6 +133,10 @@ class RCLCPP_PUBLIC Duration static Duration from_seconds(double seconds); + /// Create a duration object from an integer number representing nanoseconds + static Duration + from_nanoseconds(rcl_duration_value_t nanoseconds); + /// Convert Duration into a std::chrono::Duration. template DurationT @@ -143,6 +151,8 @@ class RCLCPP_PUBLIC Duration private: rcl_duration_t rcl_duration_; + + Duration() = default; }; } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/duration.cpp b/rclcpp/src/rclcpp/duration.cpp index 47faa0d611..40ce9daaa9 100644 --- a/rclcpp/src/rclcpp/duration.cpp +++ b/rclcpp/src/rclcpp/duration.cpp @@ -37,7 +37,7 @@ Duration::Duration(int32_t seconds, uint32_t nanoseconds) rcl_duration_.nanoseconds += nanoseconds; } -Duration::Duration(int64_t nanoseconds) +Duration::Duration(rcl_duration_value_t nanoseconds) { rcl_duration_.nanoseconds = nanoseconds; } @@ -148,7 +148,7 @@ Duration::operator+(const rclcpp::Duration & rhs) const this->rcl_duration_.nanoseconds, rhs.rcl_duration_.nanoseconds, std::numeric_limits::max()); - return Duration( + return Duration::from_nanoseconds( rcl_duration_.nanoseconds + rhs.rcl_duration_.nanoseconds); } @@ -177,7 +177,7 @@ Duration::operator-(const rclcpp::Duration & rhs) const rhs.rcl_duration_.nanoseconds, std::numeric_limits::max()); - return Duration( + return Duration::from_nanoseconds( rcl_duration_.nanoseconds - rhs.rcl_duration_.nanoseconds); } @@ -208,7 +208,7 @@ Duration::operator*(double scale) const scale, std::numeric_limits::max()); long double scale_ld = static_cast(scale); - return Duration( + return Duration::from_nanoseconds( static_cast( static_cast(rcl_duration_.nanoseconds) * scale_ld)); } @@ -249,7 +249,17 @@ Duration::to_rmw_time() const Duration Duration::from_seconds(double seconds) { - return Duration(static_cast(RCL_S_TO_NS(seconds))); + Duration ret; + ret.rcl_duration_.nanoseconds = static_cast(RCL_S_TO_NS(seconds)); + return ret; +} + +Duration +Duration::from_nanoseconds(rcl_duration_value_t nanoseconds) +{ + Duration ret; + ret.rcl_duration_.nanoseconds = nanoseconds; + return ret; } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/time.cpp b/rclcpp/src/rclcpp/time.cpp index e9d633e046..556a5e69ad 100644 --- a/rclcpp/src/rclcpp/time.cpp +++ b/rclcpp/src/rclcpp/time.cpp @@ -199,7 +199,7 @@ Time::operator-(const rclcpp::Time & rhs) const throw std::underflow_error("time subtraction leads to int64_t underflow"); } - return Duration(rcl_time_.nanoseconds - rhs.rcl_time_.nanoseconds); + return Duration::from_nanoseconds(rcl_time_.nanoseconds - rhs.rcl_time_.nanoseconds); } Time diff --git a/rclcpp/test/rclcpp/test_duration.cpp b/rclcpp/test/rclcpp/test_duration.cpp index 6e93ae019d..f3cbdffa3c 100644 --- a/rclcpp/test/rclcpp/test_duration.cpp +++ b/rclcpp/test/rclcpp/test_duration.cpp @@ -68,7 +68,7 @@ TEST_F(TestDuration, operators) { TEST_F(TestDuration, chrono_overloads) { int64_t ns = 123456789l; auto chrono_ns = std::chrono::nanoseconds(ns); - auto d1 = rclcpp::Duration(ns); + auto d1 = rclcpp::Duration::from_nanoseconds(ns); auto d2 = rclcpp::Duration(chrono_ns); auto d3 = rclcpp::Duration(123456789ns); EXPECT_EQ(d1, d2); @@ -85,11 +85,11 @@ TEST_F(TestDuration, chrono_overloads) { } TEST_F(TestDuration, overflows) { - rclcpp::Duration max(std::numeric_limits::max()); - rclcpp::Duration min(std::numeric_limits::min()); + auto max = rclcpp::Duration::from_nanoseconds(std::numeric_limits::max()); + auto min = rclcpp::Duration::from_nanoseconds(std::numeric_limits::min()); - rclcpp::Duration one(1); - rclcpp::Duration negative_one(-1); + rclcpp::Duration one(1ns); + rclcpp::Duration negative_one(-1ns); EXPECT_THROW(max + one, std::overflow_error); EXPECT_THROW(min - one, std::underflow_error); @@ -106,7 +106,7 @@ TEST_F(TestDuration, overflows) { } TEST_F(TestDuration, negative_duration) { - rclcpp::Duration assignable_duration = rclcpp::Duration(0) - rclcpp::Duration(5, 0); + rclcpp::Duration assignable_duration = rclcpp::Duration(0ns) - rclcpp::Duration(5, 0); { // avoid windows converting a literal number less than -INT_MAX to unsigned int C4146 @@ -140,22 +140,24 @@ static const int64_t ONE_SEC_IN_NS = 1000 * 1000 * 1000; static const int64_t ONE_AND_HALF_SEC_IN_NS = 3 * HALF_SEC_IN_NS; TEST_F(TestDuration, from_seconds) { - EXPECT_EQ(rclcpp::Duration(0), rclcpp::Duration::from_seconds(0.0)); - EXPECT_EQ(rclcpp::Duration(0), rclcpp::Duration::from_seconds(0)); + EXPECT_EQ(rclcpp::Duration(0ns), rclcpp::Duration::from_seconds(0.0)); + EXPECT_EQ(rclcpp::Duration(0ns), rclcpp::Duration::from_seconds(0)); EXPECT_EQ(rclcpp::Duration(1, HALF_SEC_IN_NS), rclcpp::Duration::from_seconds(1.5)); - EXPECT_EQ(rclcpp::Duration(-ONE_AND_HALF_SEC_IN_NS), rclcpp::Duration::from_seconds(-1.5)); + EXPECT_EQ( + rclcpp::Duration::from_nanoseconds(-ONE_AND_HALF_SEC_IN_NS), + rclcpp::Duration::from_seconds(-1.5)); } TEST_F(TestDuration, std_chrono_constructors) { - EXPECT_EQ(rclcpp::Duration(0), rclcpp::Duration(0.0s)); - EXPECT_EQ(rclcpp::Duration(0), rclcpp::Duration(0s)); + EXPECT_EQ(rclcpp::Duration(0ns), rclcpp::Duration(0.0s)); + EXPECT_EQ(rclcpp::Duration(0ns), rclcpp::Duration(0s)); EXPECT_EQ(rclcpp::Duration(1, HALF_SEC_IN_NS), rclcpp::Duration(1.5s)); EXPECT_EQ(rclcpp::Duration(-1, 0), rclcpp::Duration(-1s)); } TEST_F(TestDuration, conversions) { { - const rclcpp::Duration duration(HALF_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(HALF_SEC_IN_NS); const auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, 0); EXPECT_EQ(duration_msg.nanosec, HALF_SEC_IN_NS); @@ -170,7 +172,7 @@ TEST_F(TestDuration, conversions) { } { - const rclcpp::Duration duration(ONE_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(ONE_SEC_IN_NS); const auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, 1); EXPECT_EQ(duration_msg.nanosec, 0u); @@ -185,7 +187,7 @@ TEST_F(TestDuration, conversions) { } { - const rclcpp::Duration duration(ONE_AND_HALF_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(ONE_AND_HALF_SEC_IN_NS); auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, 1); EXPECT_EQ(duration_msg.nanosec, HALF_SEC_IN_NS); @@ -200,7 +202,7 @@ TEST_F(TestDuration, conversions) { } { - rclcpp::Duration duration(-HALF_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(-HALF_SEC_IN_NS); auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, -1); EXPECT_EQ(duration_msg.nanosec, HALF_SEC_IN_NS); @@ -213,7 +215,7 @@ TEST_F(TestDuration, conversions) { } { - rclcpp::Duration duration(-ONE_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(-ONE_SEC_IN_NS); auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, -1); EXPECT_EQ(duration_msg.nanosec, 0u); @@ -226,7 +228,7 @@ TEST_F(TestDuration, conversions) { } { - rclcpp::Duration duration(-ONE_AND_HALF_SEC_IN_NS); + auto duration = rclcpp::Duration::from_nanoseconds(-ONE_AND_HALF_SEC_IN_NS); auto duration_msg = static_cast(duration); EXPECT_EQ(duration_msg.sec, -2); EXPECT_EQ(duration_msg.nanosec, HALF_SEC_IN_NS); @@ -253,9 +255,10 @@ TEST_F(TestDuration, test_some_constructors) { } TEST_F(TestDuration, test_some_exceptions) { - rclcpp::Duration test_duration(0u); + rclcpp::Duration test_duration(0ns); RCLCPP_EXPECT_THROW_EQ( - test_duration = rclcpp::Duration(INT64_MAX) - rclcpp::Duration(-1), + test_duration = + rclcpp::Duration::from_nanoseconds(INT64_MAX) - rclcpp::Duration(-1ns), std::overflow_error("duration subtraction leads to int64_t overflow")); RCLCPP_EXPECT_THROW_EQ( test_duration = test_duration * (std::numeric_limits::infinity()), diff --git a/rclcpp/test/rclcpp/test_time.cpp b/rclcpp/test/rclcpp/test_time.cpp index c399e51074..f7889e96f6 100644 --- a/rclcpp/test/rclcpp/test_time.cpp +++ b/rclcpp/test/rclcpp/test_time.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -30,6 +31,8 @@ namespace { +using namespace std::chrono_literals; + bool logical_eq(const bool a, const bool b) { return (a && b) || ((!a) && !(b)); @@ -221,7 +224,7 @@ TEST_F(TestTime, operators) { EXPECT_EQ(sub, young - old); rclcpp::Time young_changed(young); - young_changed -= rclcpp::Duration(old.nanoseconds()); + young_changed -= rclcpp::Duration::from_nanoseconds(old.nanoseconds()); EXPECT_EQ(sub.nanoseconds(), young_changed.nanoseconds()); rclcpp::Time system_time(0, 0, RCL_SYSTEM_TIME); @@ -320,8 +323,8 @@ TEST_F(TestTime, overflow_detectors) { TEST_F(TestTime, overflows) { rclcpp::Time max_time(std::numeric_limits::max()); rclcpp::Time min_time(std::numeric_limits::min()); - rclcpp::Duration one(1); - rclcpp::Duration two(2); + rclcpp::Duration one(1ns); + rclcpp::Duration two(2ns); // Cross min/max EXPECT_THROW(max_time + one, std::overflow_error); @@ -394,7 +397,7 @@ TEST_F(TestTime, test_assignment_operator_from_builtin_msg_time) { } TEST_F(TestTime, test_sum_operator) { - const rclcpp::Duration one(1); + const rclcpp::Duration one(1ns); const rclcpp::Time test_time(0u); EXPECT_EQ(0u, test_time.nanoseconds()); @@ -406,41 +409,41 @@ TEST_F(TestTime, test_overflow_underflow_throws) { rclcpp::Time test_time(0u); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Time(INT64_MAX) + rclcpp::Duration(1), + test_time = rclcpp::Time(INT64_MAX) + rclcpp::Duration(1ns), std::overflow_error("addition leads to int64_t overflow")); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Time(INT64_MIN) + rclcpp::Duration(-1), + test_time = rclcpp::Time(INT64_MIN) + rclcpp::Duration(-1ns), std::underflow_error("addition leads to int64_t underflow")); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Time(INT64_MAX) - rclcpp::Duration(-1), + test_time = rclcpp::Time(INT64_MAX) - rclcpp::Duration(-1ns), std::overflow_error("time subtraction leads to int64_t overflow")); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Time(INT64_MIN) - rclcpp::Duration(1), + test_time = rclcpp::Time(INT64_MIN) - rclcpp::Duration(1ns), std::underflow_error("time subtraction leads to int64_t underflow")); test_time = rclcpp::Time(INT64_MAX); RCLCPP_EXPECT_THROW_EQ( - test_time += rclcpp::Duration(1), + test_time += rclcpp::Duration(1ns), std::overflow_error("addition leads to int64_t overflow")); test_time = rclcpp::Time(INT64_MIN); RCLCPP_EXPECT_THROW_EQ( - test_time += rclcpp::Duration(-1), + test_time += rclcpp::Duration(-1ns), std::underflow_error("addition leads to int64_t underflow")); test_time = rclcpp::Time(INT64_MAX); RCLCPP_EXPECT_THROW_EQ( - test_time -= rclcpp::Duration(-1), + test_time -= rclcpp::Duration(-1ns), std::overflow_error("time subtraction leads to int64_t overflow")); test_time = rclcpp::Time(INT64_MIN); RCLCPP_EXPECT_THROW_EQ( - test_time -= rclcpp::Duration(1), + test_time -= rclcpp::Duration(1ns), std::underflow_error("time subtraction leads to int64_t underflow")); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Duration(INT64_MAX) + rclcpp::Time(1), + test_time = rclcpp::Duration::from_nanoseconds(INT64_MAX) + rclcpp::Time(1), std::overflow_error("addition leads to int64_t overflow")); RCLCPP_EXPECT_THROW_EQ( - test_time = rclcpp::Duration(INT64_MIN) + rclcpp::Time(-1), + test_time = rclcpp::Duration::from_nanoseconds(INT64_MIN) + rclcpp::Time(-1), std::underflow_error("addition leads to int64_t underflow")); }