From 32a895de9b62618de588a050a5e49cfc7f74cc72 Mon Sep 17 00:00:00 2001 From: Yalagada Pavan Kumar Date: Tue, 13 Oct 2026 23:53:10 +0530 Subject: [PATCH 1/3] Add time_point constructor overloads and tests --- cpp-overload-test/src/lib.rs | 1 + cpp-overload-test/src/stdcpp/time_point.rs | 147 +++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 cpp-overload-test/src/stdcpp/time_point.rs diff --git a/cpp-overload-test/src/lib.rs b/cpp-overload-test/src/lib.rs index b72552c..dc280df 100644 --- a/cpp-overload-test/src/lib.rs +++ b/cpp-overload-test/src/lib.rs @@ -8,4 +8,5 @@ pub mod stdcpp { // Add new modules for each type here, in alphabetical order. pub mod forward_list; + pub mod time_point; } diff --git a/cpp-overload-test/src/stdcpp/time_point.rs b/cpp-overload-test/src/stdcpp/time_point.rs new file mode 100644 index 0000000..a734d24 --- /dev/null +++ b/cpp-overload-test/src/stdcpp/time_point.rs @@ -0,0 +1,147 @@ +//! C++ overloads tests for [std::chrono::time_point][time_point] +//! +//! This file tests three constructors that can be represented in Rust. +//! +//! ### Limitations +//! +//! C++ time points use clock and duration types. +//! This test uses fixed types instead of supporting all possible types. +//! +//! [time_point]: https://en.cppreference.com/cpp/chrono/time_point + +#![allow(unused_braces, reason = "Generated by overload! macro")] + +use cpp::cpp; +use splat_overload::overload; +use std::ffi::{c_longlong, c_void}; +use std::marker::PhantomData; + +cpp! {{ + #include + + using TestClock = std::chrono::system_clock; + using TestDuration = std::chrono::milliseconds; + using TestTimePoint = + std::chrono::time_point; + + using TestSecondsTimePoint = + std::chrono::time_point; +}} + +/// A wrapper around a C++ time point with millisecond precision. +#[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] +pub struct StdTimePoint(*mut c_void, PhantomData<()>); + +/// A Wrapper around a C++ time point with second precision. +#[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] +pub struct StdSecondsTimePoint(*mut c_void, PhantomData<()>); + +impl StdSecondsTimePoint { + /// Construct a time point from seconds since the epoch. + fn from_seconds(seconds: i64) -> Self { + let point = unsafe { + cpp!([seconds as "long long"] -> *mut c_void as + "TestSecondsTimePoint*" { + return new TestSecondsTimePoint( + std::chrono::seconds(seconds) + ); + }) + }; + + Self(point, PhantomData) + } +} + +impl StdTimePoint { + /// Construct a time point at the clock's epoch. + fn default() -> Self { + let point = unsafe { + cpp!([] -> *mut c_void as "TestTimePoint*" { + return new TestTimePoint(); + }) + }; + + Self(point, PhantomData) + } + + /// Construct a time point from milliseconds since the epoch. + fn from_duration(milliseconds: i64) -> Self { + let point = unsafe { + cpp!([milliseconds as "long long"] -> *mut c_void as + "TestTimePoint*" { + return new TestTimePoint( + TestDuration(milliseconds) + ); + }) + }; + + Self(point, PhantomData) + } + + /// Construct a millisecond time point from second time point. + fn from_other(other: &StdSecondsTimePoint) -> Self { + let other = other.0 as *const c_void; + + let point = unsafe { + cpp!([other as "const TestSecondsTimePoint*"] -> *mut + c_void as "TestTimePoint*" { + return new TestTimePoint(*other); + + }) + }; + + Self(point, PhantomData) + } + + /// Return the number of milliseconds since epoch. + fn milliseconds_since_epoch(&self) -> i64 { + let point = self.0 as *const c_void; + + unsafe { + cpp!([point as "const TestTimePoint*"] -> c_longlong as + "long long" { + return point->time_since_epoch().count(); + }) + } + } +} + +// ### Ergonomics +// C++ allows constructors with the same name but different arguments. +// +// Rust does not normallly support constructor overloading. +// The overload! macro allows these constructors to share the name new. +overload! { + impl StdTimePoint { + /// Construct time point at clock's epoch. + pub fn new() -> StdTimePoint { + StdTimePoint::default() + } + + /// Construct time point from milliseconds since the epoch. + pub fn new(milliseconds: i64) -> StdTimePoint { + StdTimePoint::from_duration(milliseconds) + } + + /// Construct time point from seconds-resolution time point. + pub fn new(other: &StdSecondsTimePoint) -> StdTimePoint { + StdTimePoint::from_other(other) + } + } +} + +#[test] +fn test_time_point_constructors() { + // Test the default constructor. + let epoch = StdTimePoint::new(); + assert_eq!(epoch.milliseconds_since_epoch(), 0); + + // Test the duration constructor. + let milliseconds = StdTimePoint::new(1500_i64); + assert_eq!(milliseconds.milliseconds_since_epoch(), 1500); + + // Test the converting constructor. + let seconds = StdSecondsTimePoint::from_seconds(2); + let converted = StdTimePoint::new(&seconds); + assert_eq!(converted.milliseconds_since_epoch(), 2000); +} From 52406dde37f937f4ee8990160220b3442c84e46e Mon Sep 17 00:00:00 2001 From: Yalagada Pavan Kumar Date: Wed, 14 Oct 2026 17:09:44 +0530 Subject: [PATCH 2/3] Fix dead code warnings --- cpp-overload-test/src/stdcpp/time_point.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cpp-overload-test/src/stdcpp/time_point.rs b/cpp-overload-test/src/stdcpp/time_point.rs index a734d24..31c2b60 100644 --- a/cpp-overload-test/src/stdcpp/time_point.rs +++ b/cpp-overload-test/src/stdcpp/time_point.rs @@ -38,6 +38,7 @@ pub struct StdSecondsTimePoint(*mut c_void, PhantomData<()>); impl StdSecondsTimePoint { /// Construct a time point from seconds since the epoch. + #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_seconds(seconds: i64) -> Self { let point = unsafe { cpp!([seconds as "long long"] -> *mut c_void as @@ -54,6 +55,7 @@ impl StdSecondsTimePoint { impl StdTimePoint { /// Construct a time point at the clock's epoch. + #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn default() -> Self { let point = unsafe { cpp!([] -> *mut c_void as "TestTimePoint*" { @@ -65,6 +67,7 @@ impl StdTimePoint { } /// Construct a time point from milliseconds since the epoch. + #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_duration(milliseconds: i64) -> Self { let point = unsafe { cpp!([milliseconds as "long long"] -> *mut c_void as @@ -79,6 +82,7 @@ impl StdTimePoint { } /// Construct a millisecond time point from second time point. + #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_other(other: &StdSecondsTimePoint) -> Self { let other = other.0 as *const c_void; @@ -94,6 +98,7 @@ impl StdTimePoint { } /// Return the number of milliseconds since epoch. + #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn milliseconds_since_epoch(&self) -> i64 { let point = self.0 as *const c_void; From 345fc9ecb602965fd070985f72cbf05642fc8256 Mon Sep 17 00:00:00 2001 From: Yalagada Pavan Kumar Date: Wed, 14 Oct 2026 17:41:27 +0530 Subject: [PATCH 3/3] Align dead code expectations --- cpp-overload-test/src/stdcpp/time_point.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cpp-overload-test/src/stdcpp/time_point.rs b/cpp-overload-test/src/stdcpp/time_point.rs index 31c2b60..b3642bc 100644 --- a/cpp-overload-test/src/stdcpp/time_point.rs +++ b/cpp-overload-test/src/stdcpp/time_point.rs @@ -36,9 +36,9 @@ pub struct StdTimePoint(*mut c_void, PhantomData<()>); #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] pub struct StdSecondsTimePoint(*mut c_void, PhantomData<()>); +#[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] impl StdSecondsTimePoint { /// Construct a time point from seconds since the epoch. - #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_seconds(seconds: i64) -> Self { let point = unsafe { cpp!([seconds as "long long"] -> *mut c_void as @@ -53,9 +53,9 @@ impl StdSecondsTimePoint { } } +#[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] impl StdTimePoint { /// Construct a time point at the clock's epoch. - #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn default() -> Self { let point = unsafe { cpp!([] -> *mut c_void as "TestTimePoint*" { @@ -67,7 +67,6 @@ impl StdTimePoint { } /// Construct a time point from milliseconds since the epoch. - #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_duration(milliseconds: i64) -> Self { let point = unsafe { cpp!([milliseconds as "long long"] -> *mut c_void as @@ -82,7 +81,6 @@ impl StdTimePoint { } /// Construct a millisecond time point from second time point. - #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn from_other(other: &StdSecondsTimePoint) -> Self { let other = other.0 as *const c_void; @@ -98,7 +96,6 @@ impl StdTimePoint { } /// Return the number of milliseconds since epoch. - #[cfg_attr(not(test), expect(dead_code, reason = "Only used in tests"))] fn milliseconds_since_epoch(&self) -> i64 { let point = self.0 as *const c_void;