From 019729d29209396e5b34017dd144b56306ff484a Mon Sep 17 00:00:00 2001 From: Esteban Pavese Date: Mon, 13 Apr 2026 15:02:51 +0200 Subject: [PATCH 1/2] MINOR: adding Reader/Writer std::optional variants, same as boost::optional ones Signed-off-by: Esteban Pavese --- .../include/flatdata/internal/Reader.h | 15 +++++++++++ .../include/flatdata/internal/Writer.h | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/flatdata-cpp/include/flatdata/internal/Reader.h b/flatdata-cpp/include/flatdata/internal/Reader.h index 74c3514f..416405d8 100644 --- a/flatdata-cpp/include/flatdata/internal/Reader.h +++ b/flatdata-cpp/include/flatdata/internal/Reader.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -154,6 +155,20 @@ struct Reader< Tagged< T, INVALID_VALUE >, offset, num_bits, struct_size_bytes > return boost::optional< U >( Reader< T, offset, num_bits, struct_size_bytes >{ data } ); } } + + template < typename U > + operator std::optional< U >( ) const + { + boost::optional< U > bopt = this; + if ( bopt ) + { + return *bopt; + } + else + { + return std::nullopt; + } + } }; } // namespace flatdata diff --git a/flatdata-cpp/include/flatdata/internal/Writer.h b/flatdata-cpp/include/flatdata/internal/Writer.h index 230e861e..7bbdd908 100644 --- a/flatdata-cpp/include/flatdata/internal/Writer.h +++ b/flatdata-cpp/include/flatdata/internal/Writer.h @@ -12,6 +12,7 @@ #include #include +#include namespace flatdata { @@ -125,6 +126,19 @@ struct Writer< Tagged< T, INVALID_VALUE >, offset, num_bits, struct_size_bytes > return Reader< Tagged< T, INVALID_VALUE >, offset, num_bits >{ data }; } + operator std::optional< T >( ) const + { + boost::optional< T > bopt = this; + if ( bopt ) + { + return *bopt; + } + else + { + return std::nullopt; + } + } + Writer& operator=( T t ) { @@ -143,6 +157,18 @@ struct Writer< Tagged< T, INVALID_VALUE >, offset, num_bits, struct_size_bytes > { Writer< T, offset, num_bits >{ data } = INVALID_VALUE; } + return *this; + } + + Writer& + operator=( std::optional< T > t ) + { + boost::optional< T > bopt; + if ( t ) + { + bopt = *t; + } + return *this = bopt; } }; From cfef398cfbd457ec240c7d200818555b39b4bf39 Mon Sep 17 00:00:00 2001 From: Esteban Pavese Date: Mon, 13 Apr 2026 16:24:19 +0200 Subject: [PATCH 2/2] added tests Signed-off-by: Esteban Pavese --- flatdata-cpp/benchmark/main.cpp | 3 --- .../include/flatdata/internal/Reader.h | 2 +- .../include/flatdata/internal/Writer.h | 2 +- flatdata-cpp/test/StructTest.cpp | 20 ++++++++++++++++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/flatdata-cpp/benchmark/main.cpp b/flatdata-cpp/benchmark/main.cpp index 3267942d..701d1ca1 100644 --- a/flatdata-cpp/benchmark/main.cpp +++ b/flatdata-cpp/benchmark/main.cpp @@ -215,17 +215,14 @@ main( int argc, char** argv ) } else if ( args.at( "lookup" ).asBool( ) ) { - size_t num_runs = args.at( "--num-runs" ).asLong( ); call_for_graph< DoLookup >( argv[ 2 ], num_nodes, num_runs ); } else if ( args.at( "bfs" ).asBool( ) ) { - size_t num_runs = args.at( "--num-runs" ).asLong( ); call_for_graph< DoBFS >( argv[ 2 ], num_nodes, num_runs ); } else if ( args.at( "dijkstra" ).asBool( ) ) { - size_t num_runs = args.at( "--num-runs" ).asLong( ); call_for_graph< DoDijkstra >( argv[ 2 ], num_nodes, num_runs ); } } diff --git a/flatdata-cpp/include/flatdata/internal/Reader.h b/flatdata-cpp/include/flatdata/internal/Reader.h index 416405d8..a84f7767 100644 --- a/flatdata-cpp/include/flatdata/internal/Reader.h +++ b/flatdata-cpp/include/flatdata/internal/Reader.h @@ -159,7 +159,7 @@ struct Reader< Tagged< T, INVALID_VALUE >, offset, num_bits, struct_size_bytes > template < typename U > operator std::optional< U >( ) const { - boost::optional< U > bopt = this; + boost::optional< U > bopt = static_cast< boost::optional< U > >( *this ); if ( bopt ) { return *bopt; diff --git a/flatdata-cpp/include/flatdata/internal/Writer.h b/flatdata-cpp/include/flatdata/internal/Writer.h index 7bbdd908..3466dc48 100644 --- a/flatdata-cpp/include/flatdata/internal/Writer.h +++ b/flatdata-cpp/include/flatdata/internal/Writer.h @@ -128,7 +128,7 @@ struct Writer< Tagged< T, INVALID_VALUE >, offset, num_bits, struct_size_bytes > operator std::optional< T >( ) const { - boost::optional< T > bopt = this; + boost::optional< T > bopt = static_cast< boost::optional< T > >( *this ); if ( bopt ) { return *bopt; diff --git a/flatdata-cpp/test/StructTest.cpp b/flatdata-cpp/test/StructTest.cpp index 2adb4baa..780b92dc 100644 --- a/flatdata-cpp/test/StructTest.cpp +++ b/flatdata-cpp/test/StructTest.cpp @@ -43,54 +43,72 @@ TEST_CASE( "Invalid values are handled", "[Struct]" ) REQUIRE( static_cast< bool >( writer.invalid_zero ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_zero ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_zero ) + == std::optional< int8_t >( 10 ) ); REQUIRE( *reader.invalid_zero == 10 ); REQUIRE( static_cast< bool >( reader.invalid_zero ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_zero ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_zero ) + == std::optional< int8_t >( 10 ) ); writer.invalid_zero = 0; REQUIRE( *writer.invalid_zero == 0 ); REQUIRE( static_cast< bool >( writer.invalid_zero ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_zero ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_zero ) == std::nullopt ); REQUIRE( *reader.invalid_zero == 0 ); REQUIRE( static_cast< bool >( reader.invalid_zero ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_zero ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_zero ) == std::nullopt ); writer.invalid_min_int = 10; REQUIRE( *writer.invalid_min_int == 10 ); REQUIRE( static_cast< bool >( writer.invalid_min_int ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_min_int ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_min_int ) + == std::optional< int8_t >( 10 ) ); REQUIRE( *reader.invalid_min_int == 10 ); REQUIRE( static_cast< bool >( reader.invalid_min_int ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_min_int ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_min_int ) + == std::optional< int8_t >( 10 ) ); writer.invalid_min_int = -128; REQUIRE( *writer.invalid_min_int == -128 ); REQUIRE( static_cast< bool >( writer.invalid_min_int ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_min_int ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_min_int ) == std::nullopt ); REQUIRE( *reader.invalid_min_int == -128 ); REQUIRE( static_cast< bool >( reader.invalid_min_int ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_min_int ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_min_int ) == std::nullopt ); writer.invalid_max_int = 10; REQUIRE( *writer.invalid_max_int == 10 ); REQUIRE( static_cast< bool >( writer.invalid_max_int ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_max_int ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_max_int ) + == std::optional< int8_t >( 10 ) ); REQUIRE( *reader.invalid_max_int == 10 ); REQUIRE( static_cast< bool >( reader.invalid_max_int ) == true ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_max_int ) == boost::optional< int8_t >( 10 ) ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_max_int ) + == std::optional< int8_t >( 10 ) ); writer.invalid_max_int = 127; REQUIRE( *writer.invalid_max_int == 127 ); REQUIRE( static_cast< bool >( writer.invalid_max_int ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( writer.invalid_max_int ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( writer.invalid_max_int ) == std::nullopt ); REQUIRE( *reader.invalid_max_int == 127 ); REQUIRE( static_cast< bool >( reader.invalid_max_int ) == false ); REQUIRE( static_cast< boost::optional< int8_t > >( reader.invalid_max_int ) == boost::none ); + REQUIRE( static_cast< std::optional< int8_t > >( reader.invalid_max_int ) == std::nullopt ); } TEST_CASE( "Invalid values can be converted to string", "[Struct]" ) @@ -102,4 +120,4 @@ TEST_CASE( "Invalid values can be converted to string", "[Struct]" ) invalid_max_int : 0, })"; REQUIRE( ( *data ).to_string( ) == EXPECTED ); -} \ No newline at end of file +}