├── .clang-format ├── .github └── workflows │ ├── code-checks.yaml │ ├── jekyll-gh-pages.yml │ ├── linux.yaml │ ├── macos.yaml │ ├── mkdocs-gh-pages.yaml │ └── windows.yaml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── banner1.png ├── benchmarks ├── CMakeLists.txt ├── README.md ├── all │ ├── CMakeLists.txt │ ├── canada_read.cpp │ ├── canada_write.cpp │ ├── licenses_read.cpp │ ├── licenses_write.cpp │ ├── main.cpp │ ├── person_read.cpp │ └── person_write.cpp ├── data │ ├── canada.json │ └── licenses.json ├── img │ ├── canada_read.png │ ├── canada_write.png │ ├── licenses_read.png │ ├── licenses_write.png │ ├── person_read.png │ └── person_write.png └── json │ ├── CMakeLists.txt │ ├── canada.cpp │ ├── licenses.cpp │ ├── main.cpp │ └── person.cpp ├── conanfile.py ├── docs ├── CNAME ├── as.md ├── assets │ ├── images │ │ ├── reflectcpp.png │ │ ├── rfl-favicon-square.png │ │ ├── rfl-favicon.png │ │ ├── rfl-robot.jpg │ │ └── rfl.png │ └── stylesheets │ │ └── tweaks.css ├── backwards_compatability.md ├── benchmarks.md ├── bytestring.md ├── c_arrays_and_inheritance.md ├── composing_validators.md ├── concepts │ ├── custom_classes.md │ ├── field_syntax.md │ ├── processors.md │ └── structs.md ├── contributing.md ├── custom_parser.md ├── docs-readme.md ├── enums.md ├── extra_fields.md ├── flatten_structs.md ├── generic.md ├── index.md ├── install.md ├── json_schema.md ├── literals.md ├── named_tuple.md ├── number_systems.md ├── object.md ├── optional_fields.md ├── patterns.md ├── replace.md ├── result.md ├── rfl_ref.md ├── rfl_skip.md ├── rfl_tuple.md ├── size_validation.md ├── standard_containers.md ├── supported_formats │ ├── avro.md │ ├── bson.md │ ├── capnproto.md │ ├── cbor.md │ ├── flexbuffers.md │ ├── json.md │ ├── msgpack.md │ ├── supporting_your_own_format.md │ ├── toml.md │ ├── ubjson.md │ ├── xml.md │ └── yaml.md ├── timestamps.md ├── to_view.md ├── validating_numbers.md └── variants_and_tagged_unions.md ├── include ├── rfl.hpp └── rfl │ ├── AddStructName.hpp │ ├── AddTagsToVariants.hpp │ ├── AllOf.hpp │ ├── AllowRawPtrs.hpp │ ├── AnyOf.hpp │ ├── Attribute.hpp │ ├── Binary.hpp │ ├── Box.hpp │ ├── Bytestring.hpp │ ├── DefaultIfMissing.hpp │ ├── Description.hpp │ ├── ExtraFields.hpp │ ├── Field.hpp │ ├── Flatten.hpp │ ├── Generic.hpp │ ├── Hex.hpp │ ├── Literal.hpp │ ├── MetaField.hpp │ ├── NamedTuple.hpp │ ├── NoExtraFields.hpp │ ├── NoFieldNames.hpp │ ├── NoOptionals.hpp │ ├── Object.hpp │ ├── Oct.hpp │ ├── OneOf.hpp │ ├── Pattern.hpp │ ├── PatternValidator.hpp │ ├── Processors.hpp │ ├── Ref.hpp │ ├── Rename.hpp │ ├── Result.hpp │ ├── Size.hpp │ ├── Skip.hpp │ ├── SnakeCaseToCamelCase.hpp │ ├── SnakeCaseToPascalCase.hpp │ ├── TaggedUnion.hpp │ ├── Timestamp.hpp │ ├── Tuple.hpp │ ├── UnderlyingEnums.hpp │ ├── Validator.hpp │ ├── Variant.hpp │ ├── always_false.hpp │ ├── apply.hpp │ ├── as.hpp │ ├── avro.hpp │ ├── avro │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Schema.hpp │ ├── SchemaImpl.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ ├── schema │ │ └── Type.hpp │ ├── to_schema.hpp │ └── write.hpp │ ├── bson.hpp │ ├── bson │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── capnproto.hpp │ ├── capnproto │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Schema.hpp │ ├── SchemaImpl.hpp │ ├── Writer.hpp │ ├── get_root_name.hpp │ ├── is_named_type.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ ├── schema │ │ ├── CapnProtoTypes.hpp │ │ └── Type.hpp │ ├── to_schema.hpp │ └── write.hpp │ ├── cbor.hpp │ ├── cbor │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── comparisons.hpp │ ├── config.hpp │ ├── default.hpp │ ├── define_literal.hpp │ ├── define_named_tuple.hpp │ ├── define_tagged_union.hpp │ ├── define_variant.hpp │ ├── enums.hpp │ ├── extract_discriminators.hpp │ ├── field_names_t.hpp │ ├── field_type.hpp │ ├── fields.hpp │ ├── flexbuf.hpp │ ├── flexbuf │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── from_generic.hpp │ ├── from_named_tuple.hpp │ ├── generic │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── read.hpp │ └── write.hpp │ ├── get.hpp │ ├── internal │ ├── Array.hpp │ ├── Field.hpp │ ├── Fields.hpp │ ├── Getter.hpp │ ├── HasValidation.hpp │ ├── Skip.hpp │ ├── StringLiteral.hpp │ ├── VisitTree.hpp │ ├── VisitorWrapper.hpp │ ├── all_fields.hpp │ ├── bind_to_tuple.hpp │ ├── copy_flattened_tuple_to_named_tuple.hpp │ ├── copy_from_named_tuple.hpp │ ├── copy_from_tuple.hpp │ ├── copy_to_field_tuple.hpp │ ├── define_literal.hpp │ ├── define_named_tuple.hpp │ ├── define_tagged_union.hpp │ ├── define_variant.hpp │ ├── element_index.hpp │ ├── enums │ │ ├── Names.hpp │ │ ├── get_enum_names.hpp │ │ └── range_defined.hpp │ ├── extract_discriminators.hpp │ ├── field_tuple_t.hpp │ ├── field_type.hpp │ ├── find_index.hpp │ ├── flattened_ptr_tuple_t.hpp │ ├── flattened_tuple_t.hpp │ ├── get_fake_object.hpp │ ├── get_field_names.hpp │ ├── get_ith_field_from_fake_object.hpp │ ├── get_meta_fields.hpp │ ├── get_type_name.hpp │ ├── has_custom_parser.hpp │ ├── has_fields.hpp │ ├── has_flatten_fields.hpp │ ├── has_reflection_method_v.hpp │ ├── has_reflection_type_v.hpp │ ├── has_reflector.hpp │ ├── has_tag_v.hpp │ ├── has_to_class_method_v.hpp │ ├── is_add_tags_to_variants_v.hpp │ ├── is_allow_raw_ptrs_v.hpp │ ├── is_array.hpp │ ├── is_attribute.hpp │ ├── is_basic_type.hpp │ ├── is_default_if_missing_v.hpp │ ├── is_description.hpp │ ├── is_empty.hpp │ ├── is_extra_fields.hpp │ ├── is_field.hpp │ ├── is_flatten_field.hpp │ ├── is_literal.hpp │ ├── is_named_tuple.hpp │ ├── is_no_extra_fields_v.hpp │ ├── is_no_field_names_v.hpp │ ├── is_no_optionals_v.hpp │ ├── is_pattern.hpp │ ├── is_rename.hpp │ ├── is_skip.hpp │ ├── is_underlying_enums_v.hpp │ ├── is_validator.hpp │ ├── is_variant.hpp │ ├── lit_name.hpp │ ├── make_tag.hpp │ ├── move_and_flatten_field_tuple.hpp │ ├── move_field_tuple_to_named_tuple.hpp │ ├── move_from_named_tuple.hpp │ ├── move_from_tuple.hpp │ ├── move_to_field_tuple.hpp │ ├── no_duplicate_field_names.hpp │ ├── nt_to_ptr_named_tuple.hpp │ ├── nth_element.hpp │ ├── nth_element_t.hpp │ ├── num_fields.hpp │ ├── processed_t.hpp │ ├── ptr_cast.hpp │ ├── ptr_field_tuple_t.hpp │ ├── ptr_named_tuple_t.hpp │ ├── ptr_tuple_t.hpp │ ├── remove_fields.hpp │ ├── remove_namespaces.hpp │ ├── remove_ptrs_nt.hpp │ ├── remove_ptrs_tup.hpp │ ├── remove_rename.hpp │ ├── strings │ │ └── strings.hpp │ ├── tag_t.hpp │ ├── to_flattened_ptr_tuple.hpp │ ├── to_ptr_field.hpp │ ├── to_ptr_field_tuple.hpp │ ├── to_ptr_named_tuple.hpp │ ├── to_ptr_tuple.hpp │ ├── to_std_array.hpp │ ├── transform_snake_case.hpp │ ├── tup_to_ptr_tuple.hpp │ ├── tuple │ │ ├── accumulate_sizes.hpp │ │ ├── apply.hpp │ │ ├── calculate_positions.hpp │ │ ├── concat.hpp │ │ └── make_from_tuple.hpp │ ├── tuple_t.hpp │ ├── variant │ │ ├── find_max_size.hpp │ │ ├── is_alternative_type.hpp │ │ ├── is_convertible_to.hpp │ │ └── result_t.hpp │ ├── wrap_in_fields.hpp │ └── wrap_in_rfl_array_t.hpp │ ├── io │ ├── load_bytes.hpp │ ├── load_string.hpp │ ├── save_bytes.hpp │ └── save_string.hpp │ ├── json.hpp │ ├── json │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ ├── schema │ │ ├── JSONSchema.hpp │ │ └── Type.hpp │ ├── to_schema.hpp │ └── write.hpp │ ├── make_from_tuple.hpp │ ├── make_named_tuple.hpp │ ├── msgpack.hpp │ ├── msgpack │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── name_t.hpp │ ├── named_tuple_t.hpp │ ├── parsing │ ├── AreReaderAndWriter.hpp │ ├── ArrayReader.hpp │ ├── CustomParser.hpp │ ├── FieldVariantParser.hpp │ ├── FieldVariantReader.hpp │ ├── IsReader.hpp │ ├── IsWriter.hpp │ ├── MapParser.hpp │ ├── MapReader.hpp │ ├── NamedTupleParser.hpp │ ├── Parent.hpp │ ├── Parser.hpp │ ├── Parser_array.hpp │ ├── Parser_base.hpp │ ├── Parser_box.hpp │ ├── Parser_bytestring.hpp │ ├── Parser_c_array.hpp │ ├── Parser_default.hpp │ ├── Parser_duration.hpp │ ├── Parser_filepath.hpp │ ├── Parser_map_like.hpp │ ├── Parser_named_tuple.hpp │ ├── Parser_optional.hpp │ ├── Parser_pair.hpp │ ├── Parser_ptr.hpp │ ├── Parser_ref.hpp │ ├── Parser_reference_wrapper.hpp │ ├── Parser_rename.hpp │ ├── Parser_result.hpp │ ├── Parser_rfl_array.hpp │ ├── Parser_rfl_tuple.hpp │ ├── Parser_rfl_variant.hpp │ ├── Parser_shared_ptr.hpp │ ├── Parser_skip.hpp │ ├── Parser_string_view.hpp │ ├── Parser_tagged_union.hpp │ ├── Parser_tuple.hpp │ ├── Parser_unique_ptr.hpp │ ├── Parser_variant.hpp │ ├── Parser_vector_like.hpp │ ├── Parser_wstring.hpp │ ├── SupportsTaggedUnions.hpp │ ├── TaggedUnionWrapper.hpp │ ├── TupleParser.hpp │ ├── TupleReader.hpp │ ├── VariantAlternativeWrapper.hpp │ ├── VectorParser.hpp │ ├── VectorReader.hpp │ ├── ViewReader.hpp │ ├── ViewReaderWithDefault.hpp │ ├── ViewReaderWithDefaultAndStrippedFieldNames.hpp │ ├── ViewReaderWithStrippedFieldNames.hpp │ ├── call_destructors_on_array_where_necessary.hpp │ ├── call_destructors_on_tuple_where_necessary.hpp │ ├── call_destructors_where_necessary.hpp │ ├── is_empty.hpp │ ├── is_forward_list.hpp │ ├── is_map_like.hpp │ ├── is_map_like_not_multimap.hpp │ ├── is_required.hpp │ ├── is_set_like.hpp │ ├── is_tagged_union_wrapper.hpp │ ├── is_vector_like.hpp │ ├── is_view_reader.hpp │ ├── make_type_name.hpp │ ├── schema │ │ ├── Definition.hpp │ │ ├── Type.hpp │ │ ├── ValidationType.hpp │ │ ├── make.hpp │ │ └── to_numeric_type.hpp │ ├── schemaful │ │ ├── IsSchemafulReader.hpp │ │ ├── IsSchemafulWriter.hpp │ │ ├── OptionalReader.hpp │ │ ├── SharedPtrReader.hpp │ │ ├── UniquePtrReader.hpp │ │ ├── VariantReader.hpp │ │ ├── tuple_to_named_tuple.hpp │ │ ├── tuple_to_named_tuple_t.hpp │ │ └── tuple_to_object.hpp │ ├── supports_attributes.hpp │ ├── tagged_union_wrapper_no_ptr.hpp │ └── to_single_error_message.hpp │ ├── patterns.hpp │ ├── remove_fields.hpp │ ├── replace.hpp │ ├── thirdparty │ ├── ctre.hpp │ ├── enchantum │ │ ├── algorithms.hpp │ │ ├── all.hpp │ │ ├── array.hpp │ │ ├── bitflags.hpp │ │ ├── bitset.hpp │ │ ├── bitwise_operators.hpp │ │ ├── common.hpp │ │ ├── details │ │ │ ├── enchantum_clang.hpp │ │ │ ├── enchantum_gcc.hpp │ │ │ ├── enchantum_msvc.hpp │ │ │ ├── format_util.hpp │ │ │ ├── generate_arrays.hpp │ │ │ ├── optional.hpp │ │ │ └── string_view.hpp │ │ ├── enchantum.hpp │ │ ├── entries.hpp │ │ ├── fmt_format.hpp │ │ ├── iostream.hpp │ │ ├── istream.hpp │ │ ├── next_value.hpp │ │ ├── ostream.hpp │ │ └── std_format.hpp │ └── yyjson.h │ ├── to_generic.hpp │ ├── to_named_tuple.hpp │ ├── to_view.hpp │ ├── toml.hpp │ ├── toml │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── tuple_cat.hpp │ ├── type_name_t.hpp │ ├── ubjson.hpp │ ├── ubjson │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── visit.hpp │ ├── xml.hpp │ ├── xml │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp │ ├── yaml.hpp │ └── yaml │ ├── Parser.hpp │ ├── Reader.hpp │ ├── Writer.hpp │ ├── load.hpp │ ├── read.hpp │ ├── save.hpp │ └── write.hpp ├── mkdocs.yaml ├── pyproject.toml ├── reflectcpp-config.cmake.in ├── src ├── reflectcpp.cpp ├── reflectcpp_avro.cpp ├── reflectcpp_bson.cpp ├── reflectcpp_capnproto.cpp ├── reflectcpp_cbor.cpp ├── reflectcpp_flexbuf.cpp ├── reflectcpp_json.cpp ├── reflectcpp_msgpack.cpp ├── reflectcpp_toml.cpp ├── reflectcpp_ubjson.cpp ├── reflectcpp_xml.cpp ├── reflectcpp_yaml.cpp ├── rfl │ ├── Generic.cpp │ ├── avro │ │ ├── SchemaImpl.cpp │ │ ├── Type.cpp │ │ ├── Writer.cpp │ │ └── to_schema.cpp │ ├── bson │ │ └── Writer.cpp │ ├── capnproto │ │ ├── Reader.cpp │ │ ├── SchemaImpl.cpp │ │ ├── Type.cpp │ │ ├── Writer.cpp │ │ └── to_schema.cpp │ ├── cbor │ │ └── Writer.cpp │ ├── flexbuf │ │ └── Writer.cpp │ ├── generic │ │ └── Writer.cpp │ ├── internal │ │ └── strings │ │ │ └── strings.cpp │ ├── json │ │ ├── Writer.cpp │ │ └── to_schema.cpp │ ├── msgpack │ │ └── Writer.cpp │ ├── parsing │ │ ├── schema │ │ │ └── Type.cpp │ │ └── schemaful │ │ │ └── tuple_to_object.cpp │ ├── toml │ │ └── Writer.cpp │ ├── ubjson │ │ └── Writer.cpp │ ├── xml │ │ └── Writer.cpp │ └── yaml │ │ └── Writer.cpp └── yyjson.c ├── tests ├── CMakeLists.txt ├── README.md ├── avro │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_field_variant_std.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map2.cpp │ ├── test_monster_example.cpp │ ├── test_optional_fields.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_readme_example3.cpp │ ├── test_ref.cpp │ ├── test_rfl_tuple.cpp │ ├── test_rfl_variant.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_shared_ptr.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_tuple.cpp │ ├── test_tutorial_example.cpp │ ├── test_tutorial_example_automated_schema.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── bson │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_oid.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── capnproto │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_field_variant_std.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map2.cpp │ ├── test_monster_example.cpp │ ├── test_optional_fields.cpp │ ├── test_optionals_in_vectors.cpp │ ├── test_person.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_readme_example3.cpp │ ├── test_ref.cpp │ ├── test_rfl_tuple.cpp │ ├── test_rfl_variant.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_shared_ptr.cpp │ ├── test_size.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_tuple.cpp │ ├── test_tutorial_example.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_variants_in_vectors.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── cbor │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_error_messages.cpp │ ├── test_extra_fields.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_integers.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_tagged_union2.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── flexbuffers │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_tagged_union2.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── generic │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_enum_range.cpp │ ├── test_enum_range_min_max.cpp │ ├── test_enum_range_size.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_optional.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── json │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_add_tag_to_rfl_variant.cpp │ ├── test_add_tag_to_variant.cpp │ ├── test_all_of.cpp │ ├── test_alphanumeric_map.cpp │ ├── test_alphanumeric_unordered_map.cpp │ ├── test_and_then.cpp │ ├── test_anonymous_fields.cpp │ ├── test_any_of.cpp │ ├── test_apply.cpp │ ├── test_apply_on_named_tuple.cpp │ ├── test_array.cpp │ ├── test_array2.cpp │ ├── test_as.cpp │ ├── test_as2.cpp │ ├── test_as_flatten.cpp │ ├── test_binary.cpp │ ├── test_box.cpp │ ├── test_box2.cpp │ ├── test_combined_processors.cpp │ ├── test_const_fields.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class2.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_custom_constructor.cpp │ ├── test_deep_nested.cpp │ ├── test_default_if_missing.cpp │ ├── test_default_if_missing_no_field_names.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_duration.cpp │ ├── test_duration_conversion.cpp │ ├── test_email.cpp │ ├── test_empty_object.cpp │ ├── test_enum1.cpp │ ├── test_enum2.cpp │ ├── test_enum3.cpp │ ├── test_enum4.cpp │ ├── test_enum5.cpp │ ├── test_enum6.cpp │ ├── test_enum7.cpp │ ├── test_error_messages.cpp │ ├── test_extra_fields.cpp │ ├── test_extra_fields_with_no_extra_fields.cpp │ ├── test_field_variant.cpp │ ├── test_field_variant_std.cpp │ ├── test_filepath.cpp │ ├── test_flag_enum1.cpp │ ├── test_flag_enum2.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_generic.cpp │ ├── test_generic2.cpp │ ├── test_hex.cpp │ ├── test_inside_function.cpp │ ├── test_integers.cpp │ ├── test_json_schema.cpp │ ├── test_json_schema2.cpp │ ├── test_json_schema3.cpp │ ├── test_json_schema4.cpp │ ├── test_json_schema_size_validation.cpp │ ├── test_leak.cpp │ ├── test_leak_arr.cpp │ ├── test_leak_rfl_tup.cpp │ ├── test_leak_tup.cpp │ ├── test_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_literal_unordered_map.cpp │ ├── test_many_fields.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_meta_fields.cpp │ ├── test_monster_example.cpp │ ├── test_movable.cpp │ ├── test_move_replace.cpp │ ├── test_multimap.cpp │ ├── test_multiset.cpp │ ├── test_named_tuple.cpp │ ├── test_no_extra_fields.cpp │ ├── test_no_extra_fields_with_default.cpp │ ├── test_no_optionals.cpp │ ├── test_object.cpp │ ├── test_oct.cpp │ ├── test_one_of.cpp │ ├── test_optional_fields.cpp │ ├── test_pointer_fields.cpp │ ├── test_readme_example.cpp │ ├── test_ref.cpp │ ├── test_reflector.cpp │ ├── test_reflector_read.cpp │ ├── test_reflector_write.cpp │ ├── test_replace.cpp │ ├── test_replace2.cpp │ ├── test_replace_flatten.cpp │ ├── test_replace_flatten2.cpp │ ├── test_replace_with_other_struct.cpp │ ├── test_replace_with_other_struct2.cpp │ ├── test_result.cpp │ ├── test_rfl_tagged_union_visit_move_only.cpp │ ├── test_rfl_tuple.cpp │ ├── test_rfl_variant.cpp │ ├── test_rfl_variant_emplace.cpp │ ├── test_rfl_variant_get_if.cpp │ ├── test_rfl_variant_holds_alternative.cpp │ ├── test_rfl_variant_swap.cpp │ ├── test_rfl_variant_visit.cpp │ ├── test_rfl_variant_visit_in_place.cpp │ ├── test_rfl_variant_visit_lvalues.cpp │ ├── test_rfl_variant_visit_move_only.cpp │ ├── test_save_load.cpp │ ├── test_segfault.cpp │ ├── test_set.cpp │ ├── test_shared_ptr.cpp │ ├── test_size.cpp │ ├── test_skip.cpp │ ├── test_skip2.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_camel_case_rename.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_snake_case_to_pascal_case_rename.cpp │ ├── test_std_ref.cpp │ ├── test_string_map.cpp │ ├── test_string_unordered_map.cpp │ ├── test_string_view.cpp │ ├── test_strip_field_names.cpp │ ├── test_tagged_union.cpp │ ├── test_tagged_union2.cpp │ ├── test_tagged_union3.cpp │ ├── test_tagged_union4.cpp │ ├── test_tagged_union5.cpp │ ├── test_template.cpp │ ├── test_timestamp.cpp │ ├── test_transform.cpp │ ├── test_tuple.cpp │ ├── test_underlying_enums.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_unnamed_namespace.cpp │ ├── test_unordered_map.cpp │ ├── test_unordered_map_with_custom_hash.cpp │ ├── test_unordered_multimap.cpp │ ├── test_unordered_multiset.cpp │ ├── test_unordered_set.cpp │ ├── test_variant.cpp │ ├── test_view.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── json_c_arrays_and_inheritance │ ├── CMakeLists.txt │ ├── test_c_array_class1.cpp │ ├── test_c_array_class2.cpp │ ├── test_c_array_class3.cpp │ ├── test_c_array_class4.cpp │ ├── test_c_array_class5.cpp │ ├── test_inheritance.cpp │ ├── test_inheritance2.cpp │ └── write_and_read.hpp ├── msgpack │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_extra_fields.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_generic_float.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_skip.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_tagged_union2.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── toml │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── ubjson │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_bytestring.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_error_messages.cpp │ ├── test_extra_fields.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_tagged_union2.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp ├── xml │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_attribute_rename.cpp │ ├── test_box.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_if_missing.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ ├── test_xml_content.cpp │ ├── test_xml_content2.cpp │ └── write_and_read.hpp └── yaml │ ├── CMakeLists.txt │ ├── test_add_struct_name.cpp │ ├── test_array.cpp │ ├── test_box.cpp │ ├── test_combined_processors.cpp │ ├── test_custom_class1.cpp │ ├── test_custom_class3.cpp │ ├── test_custom_class4.cpp │ ├── test_default_values.cpp │ ├── test_deque.cpp │ ├── test_double.cpp │ ├── test_enum.cpp │ ├── test_field_variant.cpp │ ├── test_flag_enum.cpp │ ├── test_flag_enum_with_int.cpp │ ├── test_flatten.cpp │ ├── test_flatten_anonymous.cpp │ ├── test_forward_list.cpp │ ├── test_literal.cpp │ ├── test_literal_map.cpp │ ├── test_map.cpp │ ├── test_map_with_key_validation.cpp │ ├── test_monster_example.cpp │ ├── test_readme_example.cpp │ ├── test_readme_example2.cpp │ ├── test_ref.cpp │ ├── test_save_load.cpp │ ├── test_set.cpp │ ├── test_size.cpp │ ├── test_skip.cpp │ ├── test_snake_case_to_camel_case.cpp │ ├── test_snake_case_to_pascal_case.cpp │ ├── test_string_map.cpp │ ├── test_tagged_union.cpp │ ├── test_timestamp.cpp │ ├── test_unique_ptr.cpp │ ├── test_unique_ptr2.cpp │ ├── test_variant.cpp │ ├── test_wstring.cpp │ └── write_and_read.hpp └── vcpkg.json /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle : Google 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vcpkg"] 2 | path = vcpkg 3 | url = https://github.com/microsoft/vcpkg.git 4 | -------------------------------------------------------------------------------- /banner1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/banner1.png -------------------------------------------------------------------------------- /benchmarks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2") 2 | 3 | if (MSVC) 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std:c++20 -O2") 5 | else() 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -O2") 7 | endif() 8 | 9 | add_subdirectory(all) 10 | add_subdirectory(json) 11 | -------------------------------------------------------------------------------- /benchmarks/all/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BENCHMARK_MAIN(); 4 | -------------------------------------------------------------------------------- /benchmarks/img/canada_read.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/canada_read.png -------------------------------------------------------------------------------- /benchmarks/img/canada_write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/canada_write.png -------------------------------------------------------------------------------- /benchmarks/img/licenses_read.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/licenses_read.png -------------------------------------------------------------------------------- /benchmarks/img/licenses_write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/licenses_write.png -------------------------------------------------------------------------------- /benchmarks/img/person_read.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/person_read.png -------------------------------------------------------------------------------- /benchmarks/img/person_write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/benchmarks/img/person_write.png -------------------------------------------------------------------------------- /benchmarks/json/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-json-benchmarks) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-json-benchmarks 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-json-benchmarks PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-json-benchmarks SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-json-benchmarks 15 | PRIVATE 16 | reflectcpp 17 | ) 18 | -------------------------------------------------------------------------------- /benchmarks/json/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BENCHMARK_MAIN(); 4 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | rfl.getml.com -------------------------------------------------------------------------------- /docs/assets/images/reflectcpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/docs/assets/images/reflectcpp.png -------------------------------------------------------------------------------- /docs/assets/images/rfl-favicon-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/docs/assets/images/rfl-favicon-square.png -------------------------------------------------------------------------------- /docs/assets/images/rfl-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/docs/assets/images/rfl-favicon.png -------------------------------------------------------------------------------- /docs/assets/images/rfl-robot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/docs/assets/images/rfl-robot.jpg -------------------------------------------------------------------------------- /docs/assets/images/rfl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getml/reflect-cpp/c600b9a9d6753898f18018d4b3f7403c8df32446/docs/assets/images/rfl.png -------------------------------------------------------------------------------- /docs/benchmarks.md: -------------------------------------------------------------------------------- 1 | # Benchmarks 2 | 3 | reflect-cpp conducts continuuous benchmarking across different operating systems, compilers and architectures 4 | and publishes the results on its [Actions tab](https://github.com/getml/reflect-cpp/actions). 5 | Refer to the [benchmarks folder](https://github.com/getml/reflect-cpp/tree/main/benchmarks) for details. 6 | 7 | The benchmarks show that reflect-cpp is not only very convenient, but also one the fastest JSON libraries for C++. 8 | It is faster than RapidJSON and about 10 times faster than nlohmann/json. It can be even faster than that, 9 | if you choose to use a different format supported by reflect-cpp, such as msgpack. -------------------------------------------------------------------------------- /docs/bytestring.md: -------------------------------------------------------------------------------- 1 | # `rfl::Bytestring` 2 | 3 | `rfl::Bytestring` is a simple alias: 4 | 5 | ```cpp 6 | namespace rfl { 7 | 8 | using Bytestring = std::vector; 9 | 10 | } 11 | ``` 12 | 13 | Bytestrings are supported by binary formats such as BSON, CBOR, flexbuffers and msgpack. 14 | Textual formats do not support them. 15 | -------------------------------------------------------------------------------- /docs/size_validation.md: -------------------------------------------------------------------------------- 1 | # `rfl::Size` 2 | 3 | `rfl::Size` can be used to impose constraints on any container that contains the method `.size()`, which includes `std::string`. 4 | 5 | For instance, you can a require a vector to be non-empty as follows: 6 | 7 | ```cpp 8 | using NonEmptyStringVector = 9 | rfl::Validator, rfl::Size>>; 10 | ``` 11 | 12 | Or you could require it to contain exactly zero or three elements, using validator composition: 13 | 14 | ```cpp 15 | using NoneOrThree = 16 | rfl::Validator, 17 | rfl::Size, rfl::EqualTo<3>>>>; 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/validating_numbers.md: -------------------------------------------------------------------------------- 1 | # Validating numbers 2 | 3 | reflect-cpp can also be used to impose condition on numbers. For instance, 4 | if you want an integer that is greater or equal to 10, you can do the following: 5 | 6 | ```cpp 7 | using IntGreaterThan10 = rfl::Validator>; 8 | ``` 9 | 10 | When you then use the type `IntGreaterThan10` inside you `rfl::Field`, the condition will be automatically 11 | validated. 12 | 13 | The underlying value can be retrieved using the `.value()` method. 14 | 15 | The current conditions are currently supported by reflect-cpp: 16 | 17 | - `rfl::EqualTo` 18 | - `rfl::NotEqualTo` 19 | - `rfl::Minimum` 20 | - `rfl::ExclusiveMinimum` 21 | - `rfl::Maximum` 22 | - `rfl::ExclusiveMaximum` 23 | -------------------------------------------------------------------------------- /include/rfl/AddTagsToVariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_ADDTAGSTOVARIANTS_HPP_ 2 | #define RFL_ADDTAGSTOVARIANTS_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to automatically add tags to the variants 8 | /// they might encounter. 9 | struct AddTagsToVariants { 10 | public: 11 | template 12 | static auto process(auto&& _named_tuple) { 13 | return _named_tuple; 14 | } 15 | }; 16 | 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/AllowRawPtrs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_ALLOWRAWPTRS_HPP_ 2 | #define RFL_ALLOWRAWPTRS_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to allow raw pointers. 8 | struct AllowRawPtrs { 9 | public: 10 | template 11 | static auto process(auto&& _named_tuple) { 12 | return _named_tuple; 13 | } 14 | }; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/Bytestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_BYTESTRING_HPP_ 2 | #define RFL_BYTESTRING_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace rfl { 8 | 9 | using Bytestring = std::vector; 10 | 11 | } // namespace rfl 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/DefaultIfMissing.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFAULTIFMISSING_HPP_ 2 | #define RFL_DEFAULTIFMISSING_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to use the default values for missing 8 | /// fields. 9 | struct DefaultIfMissing { 10 | public: 11 | template 12 | static auto process(auto&& _named_tuple) { 13 | return _named_tuple; 14 | } 15 | }; 16 | 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/ExtraFields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_EXTRAFIELDS_HPP_ 2 | #define RFL_EXTRAFIELDS_HPP_ 3 | 4 | #include "Object.hpp" 5 | 6 | namespace rfl { 7 | 8 | /// Used to embed additional fields for which the names cannot be known in 9 | /// advance and can therefore not be encoded in the struct. 10 | template 11 | class ExtraFields : public Object {}; 12 | 13 | } // namespace rfl 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/rfl/NoExtraFields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_NOEXTRAFIELDS_HPP_ 2 | #define RFL_NOEXTRAFIELDS_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to return an error when there are extra 8 | /// fields instead of ignoring them. 9 | struct NoExtraFields { 10 | public: 11 | template 12 | static auto process(auto&& _named_tuple) { 13 | return _named_tuple; 14 | } 15 | }; 16 | 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/NoFieldNames.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_NOFIELDNAMES_HPP_ 2 | #define RFL_NOFIELDNAMES_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to strip field names. 8 | struct NoFieldNames { 9 | public: 10 | template 11 | static auto process(auto&& _named_tuple) { 12 | return _named_tuple; 13 | } 14 | }; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/NoOptionals.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_NOOPTIONALS_HPP_ 2 | #define RFL_NOOPTIONALS_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a "fake" processor - it doesn't do much in itself, but its 7 | /// inclusion instructs the parsers to require the inclusion of all fields. 8 | struct NoOptionals { 9 | public: 10 | template 11 | static auto process(auto&& _named_tuple) { 12 | return _named_tuple; 13 | } 14 | }; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/Pattern.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PATTERN_HPP_ 2 | #define RFL_PATTERN_HPP_ 3 | 4 | #include "PatternValidator.hpp" 5 | #include "Validator.hpp" 6 | 7 | namespace rfl { 8 | 9 | template 10 | using Pattern = Validator>; 11 | 12 | } // namespace rfl 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/rfl/Skip.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_SKIP_HPP_ 2 | #define RFL_SKIP_HPP_ 3 | 4 | #include "internal/Skip.hpp" 5 | 6 | namespace rfl { 7 | 8 | template 9 | using Skip = internal::Skip; 10 | 11 | template 12 | using SkipSerialization = internal::Skip; 13 | 14 | template 15 | using SkipDeserialization = internal::Skip; 16 | 17 | } // namespace rfl 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /include/rfl/UnderlyingEnums.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_UNDERLYINGENUMS_HPP_ 2 | #define RFL_UNDERLYINGENUMS_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// This is a 'fake' processor - it doesn't do much by itself, but its 7 | /// its inclusion instructs parsers not to convert enum types to strings, but to integers 8 | struct UnderlyingEnums { 9 | public: 10 | template 11 | static auto process(auto&& _named_tuple) { 12 | return _named_tuple; 13 | } 14 | }; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/always_false.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_ALWAYSFALSE_HPP_ 2 | #define RFL_ALWAYSFALSE_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// To be used inside visitor patterns 7 | template 8 | inline constexpr bool always_false_v = false; 9 | 10 | } // namespace rfl 11 | 12 | #endif // RFL_ALWAYSFALSE_HPP_ 13 | -------------------------------------------------------------------------------- /include/rfl/avro.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_AVRO_HPP_ 2 | #define RFL_AVRO_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "avro/Parser.hpp" 6 | #include "avro/Reader.hpp" 7 | #include "avro/Schema.hpp" 8 | #include "avro/Writer.hpp" 9 | #include "avro/load.hpp" 10 | #include "avro/read.hpp" 11 | #include "avro/save.hpp" 12 | #include "avro/to_schema.hpp" 13 | #include "avro/write.hpp" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/rfl/avro/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_AVRO_LOAD_HPP_ 2 | #define RFL_AVRO_LOAD_HPP_ 3 | 4 | #include "../Processors.hpp" 5 | #include "../Result.hpp" 6 | #include "../io/load_bytes.hpp" 7 | #include "read.hpp" 8 | 9 | namespace rfl { 10 | namespace avro { 11 | 12 | template 13 | Result load(const std::string& _fname) { 14 | const auto read_bytes = [](const auto& _bytes) { 15 | return read(_bytes); 16 | }; 17 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 18 | } 19 | 20 | } // namespace avro 21 | } // namespace rfl 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/avro/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_AVRO_SAVE_HPP_ 2 | #define RFL_AVRO_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl::avro { 13 | 14 | template 15 | Result save(const std::string& _fname, const auto& _obj) { 16 | const auto write_func = [](const auto& _obj, 17 | std::ostream& _stream) -> std::ostream& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_bytes(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace rfl::avro 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/bson.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_BSON_HPP_ 2 | #define RFL_BSON_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "bson/Parser.hpp" 6 | #include "bson/Reader.hpp" 7 | #include "bson/Writer.hpp" 8 | #include "bson/load.hpp" 9 | #include "bson/read.hpp" 10 | #include "bson/save.hpp" 11 | #include "bson/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/bson/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_BSON_LOAD_HPP_ 2 | #define RFL_BSON_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_bytes.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace bson { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_bytes = [](const auto& _bytes) { 14 | return read(_bytes); 15 | }; 16 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 17 | } 18 | 19 | } // namespace bson 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/bson/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_BSON_SAVE_HPP_ 2 | #define RFL_BSON_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl { 13 | namespace bson { 14 | 15 | template 16 | Result save(const std::string& _fname, const auto& _obj) { 17 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_bytes(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace bson 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/capnproto.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CAPNPROTO_HPP_ 2 | #define RFL_CAPNPROTO_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "capnproto/Parser.hpp" 6 | #include "capnproto/Reader.hpp" 7 | #include "capnproto/Schema.hpp" 8 | #include "capnproto/Writer.hpp" 9 | #include "capnproto/load.hpp" 10 | #include "capnproto/read.hpp" 11 | #include "capnproto/save.hpp" 12 | #include "capnproto/to_schema.hpp" 13 | #include "capnproto/write.hpp" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/rfl/capnproto/is_named_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CAPNPROTO_IS_NAMED_TYPE_HPP_ 2 | #define RFL_CAPNPROTO_IS_NAMED_TYPE_HPP_ 3 | 4 | namespace rfl::capnproto { 5 | 6 | inline bool is_named_type(const parsing::schema::Type& _type) { 7 | return _type.variant_.visit([&](const auto& _v) -> bool { 8 | using T = std::remove_cvref_t; 9 | return std::is_same() || 10 | std::is_same() || 11 | std::is_same() || 12 | std::is_same(); 13 | }); 14 | } 15 | 16 | } // namespace rfl::capnproto 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /include/rfl/capnproto/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CAPNPROTO_LOAD_HPP_ 2 | #define RFL_CAPNPROTO_LOAD_HPP_ 3 | 4 | #include "../Processors.hpp" 5 | #include "../Result.hpp" 6 | #include "../io/load_bytes.hpp" 7 | #include "read.hpp" 8 | 9 | namespace rfl { 10 | namespace capnproto { 11 | 12 | template 13 | Result load(const std::string& _fname) { 14 | const auto read_bytes = [](const auto& _bytes) { 15 | return read(_bytes); 16 | }; 17 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 18 | } 19 | 20 | } // namespace capnproto 21 | } // namespace rfl 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/capnproto/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CAPNPROTO_SAVE_HPP_ 2 | #define RFL_CAPNPROTO_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl::capnproto { 13 | 14 | template 15 | Result save(const std::string& _fname, const auto& _obj) { 16 | const auto write_func = [](const auto& _obj, 17 | std::ostream& _stream) -> std::ostream& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_bytes(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace rfl::capnproto 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/cbor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CBOR_HPP_ 2 | #define RFL_CBOR_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "cbor/Parser.hpp" 6 | #include "cbor/Reader.hpp" 7 | #include "cbor/Writer.hpp" 8 | #include "cbor/load.hpp" 9 | #include "cbor/read.hpp" 10 | #include "cbor/save.hpp" 11 | #include "cbor/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/cbor/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CBOR_LOAD_HPP_ 2 | #define RFL_CBOR_LOAD_HPP_ 3 | 4 | #include "../Processors.hpp" 5 | #include "../Result.hpp" 6 | #include "../io/load_bytes.hpp" 7 | #include "read.hpp" 8 | 9 | namespace rfl::cbor { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_bytes = [](const auto& _bytes) { 14 | return read(_bytes); 15 | }; 16 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 17 | } 18 | 19 | } // namespace rfl::cbor 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/cbor/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CBOR_SAVE_HPP_ 2 | #define RFL_CBOR_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl::cbor { 13 | 14 | template 15 | Result save(const std::string& _fname, const auto& _obj) { 16 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 17 | return write(_obj, _stream); 18 | }; 19 | return rfl::io::save_bytes(_fname, _obj, write_func); 20 | } 21 | 22 | } // namespace rfl::cbor 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/config.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_CONFIG_HPP_ 2 | #define RFL_CONFIG_HPP_ 3 | 4 | namespace rfl::config { 5 | 6 | // To specify a different range for a particular enum type, specialize the 7 | // enum_range template for that enum type. 8 | template 9 | struct enum_range { 10 | // In your template specialization, uncomment these two lines and replace them 11 | // with the values of your choice. 12 | // static constexpr int min = ...; 13 | // static constexpr int max = ...; 14 | }; 15 | 16 | } // namespace rfl::config 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /include/rfl/default.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFAULT_HPP_ 2 | #define RFL_DEFAULT_HPP_ 3 | 4 | namespace rfl { 5 | 6 | /// Helper class that can be passed to a field 7 | /// to trigger the default value of the type. 8 | struct Default {}; 9 | 10 | inline static const auto default_value = Default{}; 11 | 12 | } // namespace rfl 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/rfl/define_literal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFINELITERAL_HPP_ 2 | #define RFL_DEFINELITERAL_HPP_ 3 | 4 | #include "Literal.hpp" 5 | #include "internal/define_literal.hpp" 6 | 7 | namespace rfl { 8 | 9 | /// Allows you to combine several literal types. 10 | template 11 | using define_literal_t = 12 | typename internal::define_literal::type; 13 | 14 | } // namespace rfl 15 | 16 | #endif // RFL_DEFINELITERAL_HPP_ 17 | -------------------------------------------------------------------------------- /include/rfl/define_named_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFINENAMEDTUPLE_HPP_ 2 | #define RFL_DEFINENAMEDTUPLE_HPP_ 3 | 4 | #include "NamedTuple.hpp" 5 | #include "internal/define_named_tuple.hpp" 6 | 7 | namespace rfl { 8 | 9 | template 10 | using define_named_tuple_t = 11 | typename internal::define_named_tuple::type; 12 | 13 | } // namespace rfl 14 | 15 | #endif // RFL_DEFINENAMEDTUPLE_HPP_ 16 | -------------------------------------------------------------------------------- /include/rfl/define_tagged_union.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFINETAGGEDUNION_HPP_ 2 | #define RFL_DEFINETAGGEDUNION_HPP_ 3 | 4 | #include "TaggedUnion.hpp" 5 | #include "internal/StringLiteral.hpp" 6 | #include "internal/define_tagged_union.hpp" 7 | 8 | namespace rfl { 9 | 10 | template 11 | using define_tagged_union_t = 12 | typename internal::define_tagged_union<_discriminator, 13 | TaggedUnionTypes...>::type; 14 | 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/define_variant.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_DEFINEVARIANT_HPP_ 2 | #define RFL_DEFINEVARIANT_HPP_ 3 | 4 | #include 5 | 6 | #include "internal/define_variant.hpp" 7 | 8 | namespace rfl { 9 | 10 | template 11 | using define_variant_t = typename internal::define_variant::type; 12 | 13 | } // namespace rfl 14 | 15 | #endif // RFL_DEFINEVARIANT_HPP_ 16 | -------------------------------------------------------------------------------- /include/rfl/extract_discriminators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_EXTRACTDISTRIMINATORS_HPP_ 2 | #define RFL_EXTRACTDISTRIMINATORS_HPP_ 3 | 4 | #include 5 | 6 | #include "TaggedUnion.hpp" 7 | #include "define_literal.hpp" 8 | #include "field_type.hpp" 9 | #include "internal/extract_discriminators.hpp" 10 | 11 | namespace rfl { 12 | 13 | /// Extracts a Literal containing all of the discriminators from a TaggedUnion. 14 | template 15 | using extract_discriminators_t = 16 | typename internal::extract_discriminators::type; 17 | 18 | } // namespace rfl 19 | 20 | #endif // RFL_EXTRACTDISTRIMINATORS_HPP_ 21 | -------------------------------------------------------------------------------- /include/rfl/field_names_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FIELD_NAMES_T_HPP_ 2 | #define RFL_FIELD_NAMES_T_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "internal/get_field_names.hpp" 8 | 9 | namespace rfl { 10 | 11 | /// Returns a rfl::Literal containing the field names of struct T. 12 | template 13 | using field_names_t = typename std::invoke_result< 14 | decltype(internal::get_field_names>)>::type; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/field_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FIELD_TYPE_HPP_ 2 | #define RFL_FIELD_TYPE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "internal/StringLiteral.hpp" 9 | #include "internal/field_type.hpp" 10 | 11 | namespace rfl { 12 | 13 | template 14 | using field_type_t = typename internal::FieldType<_field_name, T>::Type; 15 | 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FIELDS_HPP_ 2 | #define RFL_FIELDS_HPP_ 3 | 4 | #include "internal/get_meta_fields.hpp" 5 | #include "named_tuple_t.hpp" 6 | 7 | namespace rfl { 8 | 9 | /// Returns meta-information about the fields. 10 | template 11 | auto fields() { 12 | return internal::get_meta_fields>(); 13 | } 14 | 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/flexbuf.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FLEXBUF_HPP_ 2 | #define RFL_FLEXBUF_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "flexbuf/Parser.hpp" 6 | #include "flexbuf/Reader.hpp" 7 | #include "flexbuf/Writer.hpp" 8 | #include "flexbuf/load.hpp" 9 | #include "flexbuf/read.hpp" 10 | #include "flexbuf/save.hpp" 11 | #include "flexbuf/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/flexbuf/Parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXBUF_PARSER_HPP_ 2 | #define FLEXBUF_PARSER_HPP_ 3 | 4 | #include "../parsing/Parser.hpp" 5 | #include "Reader.hpp" 6 | #include "Writer.hpp" 7 | 8 | namespace rfl { 9 | namespace flexbuf { 10 | 11 | template 12 | using Parser = parsing::Parser; 13 | 14 | } 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/flexbuf/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FLEXBUF_LOAD_HPP_ 2 | #define RFL_FLEXBUF_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_bytes.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace flexbuf { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_bytes = [](const auto& _bytes) { 14 | return read(_bytes); 15 | }; 16 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 17 | } 18 | 19 | } // namespace flexbuf 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/flexbuf/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FLEXBUF_SAVE_HPP_ 2 | #define RFL_FLEXBUF_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl { 13 | namespace flexbuf { 14 | 15 | template 16 | Result save(const std::string& _fname, const auto& _obj) { 17 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_bytes(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace flexbuf 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/from_generic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_FROM_GENERIC_HPP_ 2 | #define RFL_FROM_GENERIC_HPP_ 3 | 4 | #include "Generic.hpp" 5 | #include "generic/read.hpp" 6 | 7 | namespace rfl { 8 | 9 | /// Generates the struct T from a named tuple. 10 | template 11 | auto from_generic(const Generic& _g) { 12 | return rfl::generic::read(_g); 13 | } 14 | 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/generic/Parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GENERIC_PARSER_HPP_ 2 | #define GENERIC_PARSER_HPP_ 3 | 4 | #include "../parsing/Parser.hpp" 5 | #include "Reader.hpp" 6 | #include "Writer.hpp" 7 | 8 | namespace rfl { 9 | namespace generic { 10 | 11 | template 12 | using Parser = parsing::Parser; 13 | 14 | } 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/generic/read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GENERIC_READ_HPP_ 2 | #define GENERIC_READ_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "../Generic.hpp" 8 | #include "../Processors.hpp" 9 | #include "../Result.hpp" 10 | #include "Parser.hpp" 11 | 12 | namespace rfl { 13 | namespace generic { 14 | 15 | /// Parses an object from a generic type. 16 | template 17 | auto read(const Generic& _g) { 18 | const auto r = Reader(); 19 | return Parser>::read(r, _g); 20 | } 21 | 22 | } // namespace generic 23 | } // namespace rfl 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/generic/write.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GENERIC_WRITE_HPP_ 2 | #define GENERIC_WRITE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../Generic.hpp" 10 | #include "../parsing/Parent.hpp" 11 | #include "Parser.hpp" 12 | 13 | namespace rfl { 14 | namespace generic { 15 | 16 | /// Writes an object to a generic. 17 | template 18 | Generic write(const auto& _t) { 19 | using T = std::remove_cvref_t; 20 | using ParentType = parsing::Parent; 21 | auto w = Writer(); 22 | Parser>::write(w, _t, typename ParentType::Root{}); 23 | return w.root(); 24 | } 25 | 26 | } // namespace generic 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/internal/Field.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_FIELD_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_FIELD_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "copy_to_field_tuple.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | using field_tuple_t = 15 | typename std::invoke_result), T>::type; 16 | 17 | } 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/internal/Fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_FIELDS_HPP_ 2 | #define RFL_INTERNAL_FIELDS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | struct Fields { 15 | std::array names_; 16 | 17 | std::unordered_map indices_; 18 | }; 19 | 20 | } // namespace internal 21 | } // namespace rfl 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/internal/HasValidation.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_HASVALIDATION_HPP_ 2 | #define RFL_INTERNAL_HASVALIDATION_HPP_ 3 | 4 | #include 5 | 6 | #include "../Result.hpp" 7 | 8 | namespace rfl { 9 | namespace internal { 10 | 11 | template 12 | concept HasValidation = requires(Class obj, T value) { 13 | { Class::validate(value) } -> std::same_as>; 14 | }; 15 | 16 | } // namespace internal 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/internal/all_fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ALLFIELDS_HPP_ 2 | #define RFL_INTERNAL_ALLFIELDS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Tuple.hpp" 9 | #include "is_field.hpp" 10 | 11 | namespace rfl { 12 | namespace internal { 13 | 14 | template 15 | constexpr bool all_fields() { 16 | if constexpr (_i == rfl::tuple_size_v) { 17 | return true; 18 | } else { 19 | using T = tuple_element_t<_i, TupleType>; 20 | return is_field_v && all_fields(); 21 | } 22 | } 23 | 24 | } // namespace internal 25 | } // namespace rfl 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/rfl/internal/copy_from_named_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_COPY_FROM_NAMED_TUPLE_HPP_ 2 | #define RFL_INTERNAL_COPY_FROM_NAMED_TUPLE_HPP_ 3 | 4 | #include "move_from_named_tuple.hpp" 5 | 6 | namespace rfl { 7 | namespace internal { 8 | 9 | /// Creates a struct of type T from a named tuple. 10 | /// All fields of the struct must be an rfl::Field. 11 | template 12 | T copy_from_named_tuple(const NamedTupleType& _n) { 13 | auto n = _n; 14 | return move_from_named_tuple(std::move(n)); 15 | } 16 | 17 | } // namespace internal 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/internal/copy_from_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_COPY_FROM_TUPLE_HPP_ 2 | #define RFL_COPY_FROM_TUPLE_HPP_ 3 | 4 | #include "move_from_tuple.hpp" 5 | 6 | namespace rfl { 7 | namespace internal { 8 | 9 | /// Creates a struct of type T from a tuple by copying the underlying 10 | /// fields. 11 | template 12 | T copy_from_tuple(const TupleType& _t) { 13 | auto t = _t; 14 | return move_from_tuple(std::move(t)); 15 | } 16 | 17 | } // namespace internal 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/internal/copy_to_field_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_COPY_TO_FIELD_TUPLE_HPP_ 2 | #define RFL_INTERNAL_COPY_TO_FIELD_TUPLE_HPP_ 3 | 4 | #include "move_to_field_tuple.hpp" 5 | 6 | namespace rfl { 7 | namespace internal { 8 | 9 | template 10 | auto copy_to_field_tuple(const T& _t) { 11 | auto t = _t; 12 | return move_to_field_tuple(std::move(t)); 13 | } 14 | 15 | } // namespace internal 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/internal/enums/range_defined.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ENUMS_RANGE_DEFINED_HPP_ 2 | #define RFL_INTERNAL_ENUMS_RANGE_DEFINED_HPP_ 3 | 4 | #include 5 | 6 | #include "../../config.hpp" 7 | 8 | namespace rfl::internal::enums { 9 | 10 | template 11 | concept range_defined = requires { 12 | { config::enum_range::min }; 13 | 14 | { config::enum_range::max }; 15 | }; 16 | 17 | } // namespace rfl::internal::enums 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/internal/field_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_FIELD_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_FIELD_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "copy_to_field_tuple.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | using field_tuple_t = 15 | typename std::invoke_result), T>::type; 16 | 17 | } 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/internal/flattened_ptr_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_FLATTENED_PTR_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_FLATTENED_PTR_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "to_flattened_ptr_tuple.hpp" 8 | 9 | namespace rfl { 10 | namespace internal { 11 | 12 | template 13 | using flattened_ptr_tuple_t = 14 | typename std::invoke_result), T>::type; 15 | 16 | } // namespace internal 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/internal/flattened_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_FLATTENED_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_FLATTENED_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "flattened_ptr_tuple_t.hpp" 9 | #include "remove_ptrs_tup.hpp" 10 | #include "../to_named_tuple.hpp" 11 | 12 | namespace rfl { 13 | namespace internal { 14 | 15 | template 16 | using flattened_tuple_t = 17 | typename remove_ptrs_tup>::TupleType; 18 | 19 | } // namespace internal 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/internal/has_custom_parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_HASCUSTOMPARSER_HPP_ 2 | #define RFL_INTERNAL_HASCUSTOMPARSER_HPP_ 3 | 4 | #include 5 | 6 | #include "../parsing/Parser.hpp" 7 | 8 | namespace rfl::internal { 9 | 10 | template 11 | concept has_custom_parser = requires( 12 | const T& _t, const typename parsing::Parser< 13 | R, W, T, ProcessorsType>::CustomParserHelperStruct& _h) { 14 | { 15 | std::remove_cvref_t::from_class(_t) 16 | } -> std::same_as>; 17 | 18 | { _h.to_class() } -> std::same_as; 19 | }; 20 | 21 | } // namespace rfl::internal 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/internal/has_reflector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_HASREFLECTOR_HPP_ 2 | #define RFL_INTERNAL_HASREFLECTOR_HPP_ 3 | 4 | #include 5 | 6 | namespace rfl { 7 | template 8 | struct Reflector; 9 | 10 | namespace internal { 11 | 12 | template 13 | concept has_write_reflector = requires(Type&& item) { 14 | Reflector::from(item); 15 | }; 16 | 17 | template 18 | concept has_read_reflector = 19 | requires(const typename Reflector::ReflType& item) { 20 | Reflector::to(item); 21 | }; 22 | 23 | } // namespace internal 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/internal/is_allow_raw_ptrs_v.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISALLOWRAWPTRS_HPP_ 2 | #define RFL_INTERNAL_ISALLOWRAWPTRS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../AllowRawPtrs.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | class is_allow_raw_ptrs; 15 | 16 | template 17 | class is_allow_raw_ptrs : public std::false_type {}; 18 | 19 | template <> 20 | class is_allow_raw_ptrs : public std::true_type {}; 21 | 22 | template 23 | constexpr bool is_allow_raw_ptrs_v = 24 | is_allow_raw_ptrs>>::value; 25 | 26 | } // namespace internal 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/internal/is_array.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISARRAY_HPP_ 2 | #define RFL_INTERNAL_ISARRAY_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "Array.hpp" 9 | 10 | namespace rfl::internal { 11 | 12 | template 13 | class is_array; 14 | 15 | template 16 | class is_array : public std::false_type {}; 17 | 18 | template 19 | class is_array> : public std::true_type {}; 20 | 21 | template 22 | constexpr bool is_array_v = 23 | is_array>>::value; 24 | 25 | } // namespace rfl::internal 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/rfl/internal/is_attribute.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISATTRIBUTE_HPP_ 2 | #define RFL_INTERNAL_ISATTRIBUTE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Attribute.hpp" 9 | #include "../Field.hpp" 10 | #include "remove_rename.hpp" 11 | 12 | namespace rfl { 13 | namespace internal { 14 | 15 | template 16 | class is_attribute; 17 | 18 | template 19 | class is_attribute : public std::false_type {}; 20 | 21 | template 22 | class is_attribute> : public std::true_type {}; 23 | 24 | template 25 | constexpr bool is_attribute_v = is_attribute>::value; 26 | 27 | } // namespace internal 28 | } // namespace rfl 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/rfl/internal/is_basic_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISBASICTYPE_HPP_ 2 | #define RFL_INTERNAL_ISBASICTYPE_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace rfl { 8 | namespace internal { 9 | 10 | template 11 | constexpr bool is_basic_type_v = 12 | std::is_floating_point_v> || 13 | std::is_integral_v> || 14 | std::is_same, std::string>() || 15 | std::is_same, bool>(); 16 | 17 | } // namespace internal 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/internal/is_empty.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISEMPTY_HPP_ 2 | #define RFL_INTERNAL_ISEMPTY_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "../Tuple.hpp" 8 | #include "is_named_tuple.hpp" 9 | 10 | namespace rfl::internal { 11 | 12 | template 13 | constexpr bool is_empty() { 14 | using U = std::remove_cvref_t>; 15 | if constexpr (is_named_tuple_v) { 16 | return U::size() == 0; 17 | } else { 18 | using TupleType = ptr_tuple_t; 19 | return rfl::tuple_size_v == 0; 20 | } 21 | } 22 | 23 | } // namespace rfl::internal 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/internal/is_extra_fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISEXTRAFIELDS_HPP_ 2 | #define RFL_INTERNAL_ISEXTRAFIELDS_HPP_ 3 | 4 | #include 5 | 6 | #include "../ExtraFields.hpp" 7 | 8 | namespace rfl::internal { 9 | 10 | template 11 | class is_extra_fields; 12 | 13 | template 14 | class is_extra_fields : public std::false_type {}; 15 | 16 | template 17 | class is_extra_fields> : public std::true_type {}; 18 | 19 | template 20 | constexpr bool is_extra_fields_v = 21 | is_extra_fields>>::value; 22 | 23 | } // namespace rfl::internal 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/internal/is_field.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISFIELD_HPP_ 2 | #define RFL_INTERNAL_ISFIELD_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Field.hpp" 9 | #include "StringLiteral.hpp" 10 | 11 | namespace rfl { 12 | namespace internal { 13 | 14 | template 15 | class is_field; 16 | 17 | template 18 | class is_field : public std::false_type {}; 19 | 20 | template 21 | class is_field> : public std::true_type {}; 22 | 23 | template 24 | constexpr bool is_field_v = 25 | is_field>>::value; 26 | 27 | } // namespace internal 28 | } // namespace rfl 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/rfl/internal/is_flatten_field.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISFLATTENFIELD_HPP_ 2 | #define RFL_INTERNAL_ISFLATTENFIELD_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Flatten.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | class is_flatten_field; 15 | 16 | template 17 | class is_flatten_field : public std::false_type {}; 18 | 19 | template 20 | class is_flatten_field> : public std::true_type {}; 21 | 22 | template 23 | constexpr bool is_flatten_field_v = 24 | is_flatten_field>>::value; 25 | 26 | } // namespace internal 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/internal/is_literal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISLITERAL_HPP_ 2 | #define RFL_INTERNAL_ISLITERAL_HPP_ 3 | 4 | #include 5 | 6 | #include "../Literal.hpp" 7 | #include "StringLiteral.hpp" 8 | 9 | namespace rfl { 10 | namespace internal { 11 | 12 | template 13 | class is_literal; 14 | 15 | template 16 | class is_literal : public std::false_type {}; 17 | 18 | template 19 | class is_literal> : public std::true_type {}; 20 | 21 | template 22 | constexpr bool is_literal_v = 23 | is_literal>>::value; 24 | 25 | } // namespace internal 26 | } // namespace rfl 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/rfl/internal/is_named_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_IS_NAMED_TUPLE_HPP_ 2 | #define RFL_INTERNAL_IS_NAMED_TUPLE_HPP_ 3 | 4 | #include 5 | 6 | #include "../NamedTuple.hpp" 7 | 8 | namespace rfl { 9 | namespace internal { 10 | 11 | template 12 | class is_named_tuple; 13 | 14 | template 15 | class is_named_tuple : public std::false_type {}; 16 | 17 | template 18 | class is_named_tuple> : public std::true_type {}; 19 | 20 | template 21 | constexpr bool is_named_tuple_v = 22 | is_named_tuple>>::value; 23 | 24 | } // namespace internal 25 | } // namespace rfl 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/rfl/internal/is_no_field_names_v.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISNOFIELDNAMES_HPP_ 2 | #define RFL_INTERNAL_ISNOFIELDNAMES_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../NoFieldNames.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | class is_no_field_names; 15 | 16 | template 17 | class is_no_field_names : public std::false_type {}; 18 | 19 | template <> 20 | class is_no_field_names : public std::true_type {}; 21 | 22 | template 23 | constexpr bool is_no_field_names_v = 24 | is_no_field_names>>::value; 25 | 26 | } // namespace internal 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/internal/is_no_optionals_v.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISNOOPTIONALS_HPP_ 2 | #define RFL_INTERNAL_ISNOOPTIONALS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../NoOptionals.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | class is_no_optionals; 15 | 16 | template 17 | class is_no_optionals : public std::false_type {}; 18 | 19 | template <> 20 | class is_no_optionals : public std::true_type {}; 21 | 22 | template 23 | constexpr bool is_no_optionals_v = 24 | is_no_optionals>>::value; 25 | 26 | } // namespace internal 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/internal/is_pattern.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISPATTERN_HPP_ 2 | #define RFL_INTERNAL_ISPATTERN_HPP_ 3 | 4 | #include 5 | 6 | #include "../Pattern.hpp" 7 | #include "StringLiteral.hpp" 8 | 9 | namespace rfl { 10 | namespace internal { 11 | 12 | template 13 | class is_pattern; 14 | 15 | template 16 | class is_pattern : public std::false_type {}; 17 | 18 | template 19 | class is_pattern> : public std::true_type {}; 20 | 21 | template 22 | constexpr bool is_pattern_v = 23 | is_pattern>>::value; 24 | 25 | } // namespace internal 26 | } // namespace rfl 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/rfl/internal/is_skip.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISSKIP_HPP_ 2 | #define RFL_INTERNAL_ISSKIP_HPP_ 3 | 4 | #include 5 | 6 | #include "Skip.hpp" 7 | 8 | namespace rfl::internal { 9 | 10 | template 11 | class is_skip; 12 | 13 | template 14 | class is_skip : public std::false_type {}; 15 | 16 | template 17 | class is_skip> 18 | : public std::true_type {}; 19 | 20 | template 21 | constexpr bool is_skip_v = 22 | is_skip>>::value; 23 | 24 | } // namespace rfl::internal 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/internal/is_validator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISVALIDATOR_HPP_ 2 | #define RFL_INTERNAL_ISVALIDATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "../Validator.hpp" 7 | #include "StringLiteral.hpp" 8 | 9 | namespace rfl { 10 | namespace internal { 11 | 12 | template 13 | class is_validator; 14 | 15 | template 16 | class is_validator : public std::false_type {}; 17 | 18 | template 19 | class is_validator> : public std::true_type {}; 20 | 21 | template 22 | constexpr bool is_validator_v = 23 | is_validator>>::value; 24 | 25 | } // namespace internal 26 | } // namespace rfl 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/rfl/internal/is_variant.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_ISVARIANT_HPP_ 2 | #define RFL_INTERNAL_ISVARIANT_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace rfl { 8 | namespace internal { 9 | 10 | template 11 | class is_variant; 12 | 13 | template 14 | class is_variant : public std::false_type {}; 15 | 16 | template 17 | class is_variant> : public std::true_type {}; 18 | 19 | template 20 | constexpr bool is_variant_v = 21 | is_variant>>::value; 22 | 23 | } // namespace internal 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/internal/lit_name.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_LIT_NAME_HPP_ 2 | #define RFL_INTERNAL_LIT_NAME_HPP_ 3 | 4 | #include "../Literal.hpp" 5 | 6 | namespace rfl { 7 | namespace internal { 8 | 9 | template 10 | struct lit_name; 11 | 12 | template 13 | struct lit_name> { 14 | constexpr static auto name_ = _name; 15 | }; 16 | 17 | template 18 | constexpr auto lit_name_v = lit_name::name_; 19 | 20 | } // namespace internal 21 | } // namespace rfl 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/internal/nth_element_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_NTH_ELEMENT_T_HPP_ 2 | #define RFL_INTERNAL_NTH_ELEMENT_T_HPP_ 3 | 4 | #include 5 | 6 | #include "nth_element.hpp" 7 | 8 | namespace rfl::internal { 9 | 10 | #if defined(__clang__) 11 | 12 | template 13 | using nth_element_t = __type_pack_element; 14 | 15 | #else 16 | 17 | template 18 | struct TypeWrapper { 19 | using Type = T; 20 | }; 21 | 22 | template 23 | using nth_element_t = 24 | typename std::invoke_result_t...>), 25 | TypeWrapper...>::Type; 26 | 27 | #endif 28 | 29 | } // namespace rfl::internal 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/rfl/internal/ptr_cast.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_PTRCAST_HPP_ 2 | #define RFL_INTERNAL_PTRCAST_HPP_ 3 | 4 | #include 5 | 6 | namespace rfl::internal { 7 | 8 | /// Normally, we would use std::launder(reinterpret_cast<...>(...)), 9 | /// but there are weird issues on GCC 12 under certain compiler settings, 10 | /// so we are using this workaround instead. 11 | 12 | template 13 | inline T1 ptr_cast(T2* _ptr) { 14 | return static_cast(static_cast(_ptr)); 15 | } 16 | 17 | template 18 | inline T1 ptr_cast(const T2* _ptr) { 19 | return static_cast(static_cast(_ptr)); 20 | } 21 | 22 | } // namespace rfl::internal 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/internal/ptr_field_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_PTR_NAMED_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_PTR_NAMED_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "to_ptr_field_tuple.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | using ptr_field_tuple_t = decltype(to_ptr_field_tuple(std::declval())); 15 | 16 | } // namespace internal 17 | } // namespace rfl 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/internal/ptr_named_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_PTR_FIELD_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_PTR_FIELD_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "is_named_tuple.hpp" 9 | #include "to_ptr_named_tuple.hpp" 10 | 11 | namespace rfl { 12 | namespace internal { 13 | 14 | template 15 | using ptr_named_tuple_t = 16 | typename std::invoke_result), T>::type; 17 | 18 | } // namespace internal 19 | } // namespace rfl 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/internal/ptr_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_PTR_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_PTR_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "to_ptr_tuple.hpp" 8 | 9 | namespace rfl { 10 | namespace internal { 11 | 12 | template 13 | using ptr_tuple_t = decltype(to_ptr_tuple(std::declval())); 14 | 15 | } // namespace internal 16 | } // namespace rfl 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/rfl/internal/remove_ptrs_tup.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_REMOVE_PTRS_TUP_HPP_ 2 | #define RFL_INTERNAL_REMOVE_PTRS_TUP_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "../Tuple.hpp" 8 | #include "../to_named_tuple.hpp" 9 | #include "ptr_tuple_t.hpp" 10 | 11 | namespace rfl { 12 | namespace internal { 13 | 14 | template 15 | struct remove_ptrs_tup; 16 | 17 | template 18 | struct remove_ptrs_tup> { 19 | using TupleType = 20 | rfl::Tuple>...>; 21 | }; 22 | 23 | } // namespace internal 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/internal/tag_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_TAG_T_HPP_ 2 | #define RFL_INTERNAL_TAG_T_HPP_ 3 | 4 | #include 5 | 6 | #include "StringLiteral.hpp" 7 | #include "make_tag.hpp" 8 | 9 | namespace rfl::internal { 10 | 11 | template 12 | using tag_t = std::invoke_result_t), T>; 13 | 14 | } // namespace rfl::internal 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/rfl/internal/to_ptr_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_TO_PTR_TUPLE_HPP_ 2 | #define RFL_INTERNAL_TO_PTR_TUPLE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "bind_to_tuple.hpp" 9 | 10 | namespace rfl { 11 | namespace internal { 12 | 13 | template 14 | auto to_ptr_tuple(T& _t) { 15 | if constexpr (std::is_pointer_v>) { 16 | return to_ptr_tuple(*_t); 17 | } else { 18 | return bind_to_tuple(_t); 19 | } 20 | } 21 | 22 | } // namespace internal 23 | } // namespace rfl 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/internal/tup_to_ptr_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_TUP_TO_PTR_TUPLE_HPP_ 2 | #define RFL_INTERNAL_TUP_TO_PTR_TUPLE_HPP_ 3 | 4 | #include 5 | 6 | #include "../Field.hpp" 7 | #include "../Tuple.hpp" 8 | #include "../apply.hpp" 9 | #include "../make_named_tuple.hpp" 10 | 11 | namespace rfl { 12 | namespace internal { 13 | 14 | /// Generates a named tuple that contains pointers to the original values in 15 | /// the struct from a tuple. 16 | template 17 | auto tup_to_ptr_tuple(TupleType& _t) { 18 | const auto to_ptr = [](auto&... _fields) { 19 | return rfl::make_tuple(&_fields...); 20 | }; 21 | return rfl::apply(to_ptr, _t); 22 | } 23 | 24 | } // namespace internal 25 | } // namespace rfl 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/rfl/internal/tuple/make_from_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_TUPLE_MAKE_FROM_TUPLE_HPP_ 2 | #define RFL_INTERNAL_TUPLE_MAKE_FROM_TUPLE_HPP_ 3 | 4 | #include 5 | 6 | #include "../../Tuple.hpp" 7 | 8 | namespace rfl::internal::tuple { 9 | 10 | template 11 | T make_from_tuple(const rfl::Tuple& _t1, 12 | std::integer_sequence) { 13 | return T{rfl::get<_is>(_t1)...}; 14 | } 15 | 16 | template 17 | T make_from_tuple(rfl::Tuple&& _t1, 18 | std::integer_sequence) { 19 | return T{std::move(rfl::get<_is>(_t1))...}; 20 | } 21 | 22 | } // namespace rfl::internal::tuple 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/internal/tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_TUPLE_T_HPP_ 2 | #define RFL_INTERNAL_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ptr_tuple_t.hpp" 9 | #include "remove_ptrs_tup.hpp" 10 | #include "../to_named_tuple.hpp" 11 | 12 | namespace rfl { 13 | namespace internal { 14 | 15 | template 16 | using tuple_t = typename remove_ptrs_tup>::TupleType; 17 | 18 | } // namespace internal 19 | } // namespace rfl 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/internal/variant/is_alternative_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_VARIANT_IS_ALTERNATIVE_TYPE_HPP_ 2 | #define RFL_INTERNAL_VARIANT_IS_ALTERNATIVE_TYPE_HPP_ 3 | 4 | #include 5 | 6 | #include "../element_index.hpp" 7 | 8 | namespace rfl::internal::variant { 9 | 10 | template 11 | static constexpr bool is_alternative_type() { 12 | return internal::element_index, 13 | std::remove_cvref_t...>() != 14 | -1; 15 | } 16 | 17 | } // namespace rfl::internal::variant 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/rfl/internal/variant/is_convertible_to.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_VARIANT_IS_CONVERTIBLE_TO_HPP_ 2 | #define RFL_INTERNAL_VARIANT_IS_CONVERTIBLE_TO_HPP_ 3 | 4 | #include 5 | 6 | #include "../element_index.hpp" 7 | 8 | namespace rfl::internal::variant { 9 | 10 | template 11 | static constexpr bool is_convertible_to() { 12 | return std::disjunction_v...>; 13 | } 14 | 15 | } // namespace rfl::internal::variant 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/internal/variant/result_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_VARIANT_RESULT_T_HPP_ 2 | #define RFL_INTERNAL_VARIANT_RESULT_T_HPP_ 3 | 4 | #include 5 | 6 | #include "../nth_element_t.hpp" 7 | 8 | namespace rfl::internal::variant { 9 | 10 | template 11 | using result_t = std::remove_cv_t, internal::nth_element_t<0, AlternativeTypes...>&>>; 13 | 14 | } // namespace rfl::internal::variant 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/rfl/internal/wrap_in_rfl_array_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_ 2 | #define RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_ 3 | 4 | #include 5 | 6 | #include "Array.hpp" 7 | 8 | namespace rfl { 9 | namespace internal { 10 | 11 | template 12 | struct wrap_in_rfl_array { 13 | using type = T; 14 | }; 15 | 16 | template 17 | requires std::is_array_v 18 | struct wrap_in_rfl_array { 19 | using type = Array; 20 | }; 21 | 22 | template 23 | using wrap_in_rfl_array_t = typename wrap_in_rfl_array::type; 24 | 25 | } // namespace internal 26 | } // namespace rfl 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/rfl/io/load_bytes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_IO_LOAD_BYTES_HPP_ 2 | #define RFL_IO_LOAD_BYTES_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../Result.hpp" 10 | 11 | namespace rfl { 12 | namespace io { 13 | 14 | inline Result> load_bytes(const std::string& _fname) { 15 | std::ifstream input(_fname, std::ios::binary); 16 | if (input.is_open()) { 17 | std::istreambuf_iterator begin(input), end; 18 | const auto bytes = std::vector(begin, end); 19 | input.close(); 20 | return bytes; 21 | } else { 22 | return error("File '" + _fname + "' not found!"); 23 | } 24 | } 25 | 26 | } // namespace io 27 | } // namespace rfl 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/rfl/io/save_string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_IO_SAVE_STRING_HPP_ 2 | #define RFL_IO_SAVE_STRING_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | 10 | namespace rfl { 11 | namespace io { 12 | 13 | template 14 | Result save_string(const std::string& _fname, const T& _obj, 15 | const WriteFunction& _write) { 16 | try { 17 | std::ofstream outfile; 18 | outfile.open(_fname); 19 | _write(_obj, outfile); 20 | outfile.close(); 21 | } catch (std::exception& e) { 22 | return error(e.what()); 23 | } 24 | return Nothing{}; 25 | } 26 | 27 | } // namespace io 28 | } // namespace rfl 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/rfl/json.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_JSON_HPP_ 2 | #define RFL_JSON_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "json/Parser.hpp" 6 | #include "json/Reader.hpp" 7 | #include "json/Writer.hpp" 8 | #include "json/load.hpp" 9 | #include "json/read.hpp" 10 | #include "json/save.hpp" 11 | #include "json/to_schema.hpp" 12 | #include "json/write.hpp" 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/rfl/json/Parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_JSON_PARSER_HPP_ 2 | #define RFL_JSON_PARSER_HPP_ 3 | 4 | #include "../parsing/Parser.hpp" 5 | #include "Reader.hpp" 6 | #include "Writer.hpp" 7 | 8 | namespace rfl::json { 9 | 10 | template 11 | using Parser = parsing::Parser; 12 | 13 | } // namespace rfl::json 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/rfl/json/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_JSON_LOAD_HPP_ 2 | #define RFL_JSON_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_string.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace json { 10 | 11 | template 12 | Result load(const std::string& _fname, const yyjson_read_flag _flag = 0) { 13 | const auto read_string = [_flag](const auto& _str) { 14 | return read(_str, _flag); 15 | }; 16 | return rfl::io::load_string(_fname).and_then(read_string); 17 | } 18 | 19 | } // namespace json 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/json/schema/JSONSchema.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_JSON_SCHEMA_JSONSCHEMA_HPP_ 2 | #define RFL_JSON_SCHEMA_JSONSCHEMA_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../../Flatten.hpp" 9 | #include "../../Literal.hpp" 10 | #include "../../Rename.hpp" 11 | #include "Type.hpp" 12 | 13 | namespace rfl::json::schema { 14 | 15 | template 16 | struct JSONSchema { 17 | Rename<"$schema", Literal<"https://json-schema.org/draft/2020-12/schema">> 18 | schema; 19 | Flatten root; 20 | std::map definitions; 21 | }; 22 | 23 | } // namespace rfl::json::schema 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/make_from_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_MAKE_FROM_TUPLE_HPP_ 2 | #define RFL_MAKE_FROM_TUPLE_HPP_ 3 | 4 | #include 5 | 6 | #include "Tuple.hpp" 7 | #include "internal/tuple/make_from_tuple.hpp" 8 | 9 | namespace rfl { 10 | 11 | template 12 | auto make_from_tuple(const rfl::Tuple& _tup) { 13 | return internal::tuple::make_from_tuple( 14 | _tup, std::make_integer_sequence()); 15 | } 16 | 17 | template 18 | auto make_from_tuple(rfl::Tuple&& _tup) { 19 | return internal::tuple::make_from_tuple( 20 | std::move(_tup), std::make_integer_sequence()); 21 | } 22 | 23 | } // namespace rfl 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rfl/msgpack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_MSGPACK_HPP_ 2 | #define RFL_MSGPACK_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "msgpack/Parser.hpp" 6 | #include "msgpack/Reader.hpp" 7 | #include "msgpack/Writer.hpp" 8 | #include "msgpack/load.hpp" 9 | #include "msgpack/read.hpp" 10 | #include "msgpack/save.hpp" 11 | #include "msgpack/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/msgpack/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_MSGPACK_LOAD_HPP_ 2 | #define RFL_MSGPACK_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_bytes.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace msgpack { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_bytes = [](const auto& _bytes) { 14 | return read(_bytes); 15 | }; 16 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 17 | } 18 | 19 | } // namespace msgpack 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/msgpack/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_MSGPACK_SAVE_HPP_ 2 | #define RFL_MSGPACK_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl { 13 | namespace msgpack { 14 | 15 | template 16 | Result save(const std::string& _fname, const auto& _obj) { 17 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_bytes(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace msgpack 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/name_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_NAME_T_HPP_ 2 | #define RFL_NAME_T_HPP_ 3 | 4 | #include 5 | 6 | namespace rfl { 7 | 8 | /// Convenience class to retrieve the name of a field. 9 | template 10 | using name_t = typename std::remove_cvref_t::Name; 11 | 12 | } // namespace rfl 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/rfl/named_tuple_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_NAMED_TUPLE_T_HPP_ 2 | #define RFL_NAMED_TUPLE_T_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "NamedTuple.hpp" 9 | #include "internal/ptr_named_tuple_t.hpp" 10 | #include "internal/remove_ptrs_nt.hpp" 11 | #include "to_named_tuple.hpp" 12 | 13 | namespace rfl { 14 | 15 | /// Generates the named tuple that is equivalent to the struct T. 16 | /// This is the result you would expect from calling to_named_tuple(my_struct). 17 | /// All fields of the struct must be an rfl::Field. 18 | template 19 | using named_tuple_t = typename internal::remove_ptrs_nt< 20 | internal::ptr_named_tuple_t>::NamedTupleType; 21 | 22 | } // namespace rfl 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/parsing/AreReaderAndWriter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_AREREADERANDWRITER_HPP_ 2 | #define RFL_PARSING_AREREADERANDWRITER_HPP_ 3 | 4 | #include "IsReader.hpp" 5 | #include "IsWriter.hpp" 6 | 7 | namespace rfl { 8 | namespace parsing { 9 | 10 | template 11 | concept AreReaderAndWriter = IsReader && IsWriter; 12 | 13 | } // namespace parsing 14 | } // namespace rfl 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/rfl/parsing/Parser_base.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_PARSER_BASE_HPP_ 2 | #define RFL_PARSING_PARSER_BASE_HPP_ 3 | 4 | #include "AreReaderAndWriter.hpp" 5 | 6 | namespace rfl { 7 | namespace parsing { 8 | 9 | template 10 | requires AreReaderAndWriter 11 | struct Parser; 12 | 13 | } // namespace parsing 14 | } // namespace rfl 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/rfl/parsing/Parser_rfl_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_PARSER_RFL_TUPLE_HPP_ 2 | #define RFL_PARSING_PARSER_RFL_TUPLE_HPP_ 3 | 4 | #include "../Tuple.hpp" 5 | #include "Parser_base.hpp" 6 | #include "TupleParser.hpp" 7 | 8 | namespace rfl { 9 | namespace parsing { 10 | 11 | template 12 | requires AreReaderAndWriter> 13 | struct Parser, ProcessorsType> 14 | : public TupleParser> { 17 | }; 18 | 19 | } // namespace parsing 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/parsing/Parser_tuple.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_PARSER_TUPLE_HPP_ 2 | #define RFL_PARSING_PARSER_TUPLE_HPP_ 3 | 4 | #include 5 | 6 | #include "Parser_base.hpp" 7 | #include "TupleParser.hpp" 8 | 9 | namespace rfl { 10 | namespace parsing { 11 | 12 | template 13 | requires AreReaderAndWriter> 14 | struct Parser, ProcessorsType> 15 | : public TupleParser> { 18 | }; 19 | 20 | } // namespace parsing 21 | } // namespace rfl 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/rfl/parsing/is_forward_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_IS_FORWARD_LIST_HPP_ 2 | #define RFL_PARSING_IS_FORWARD_LIST_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace rfl { 8 | namespace parsing { 9 | 10 | template 11 | class is_forward_list; 12 | 13 | template 14 | class is_forward_list : public std::false_type {}; 15 | 16 | template 17 | class is_forward_list> : public std::true_type {}; 18 | 19 | } // namespace parsing 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/parsing/is_view_reader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_ISVIEWREADER_HPP_ 2 | #define RFL_PARSING_ISVIEWREADER_HPP_ 3 | 4 | #include "ViewReader.hpp" 5 | 6 | namespace rfl ::parsing { 7 | 8 | template 9 | class is_view_reader; 10 | 11 | template 12 | class is_view_reader : public std::false_type {}; 13 | 14 | template 15 | class is_view_reader> 16 | : public std::true_type {}; 17 | 18 | template 19 | constexpr bool is_view_reader_v = 20 | is_view_reader>>::value; 21 | 22 | } // namespace rfl::parsing 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/parsing/schema/Definition.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_SCHEMA_DEFINITION_HPP_ 2 | #define RFL_PARSING_SCHEMA_DEFINITION_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Type.hpp" 8 | 9 | namespace rfl::parsing::schema { 10 | 11 | struct Definition { 12 | /// Contains the root element of the schema definition. 13 | Type root_; 14 | 15 | /// Contains the definitions to be referenced by Type::Reference. 16 | std::map definitions_; 17 | }; 18 | 19 | } // namespace rfl::parsing::schema 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/parsing/schema/make.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_SCHEMA_MAKE_HPP_ 2 | #define RFL_PARSING_SCHEMA_MAKE_HPP_ 3 | 4 | #include 5 | 6 | #include "../Parser.hpp" 7 | #include "Definition.hpp" 8 | #include "Type.hpp" 9 | 10 | namespace rfl::parsing::schema { 11 | 12 | template 13 | Definition make() { 14 | std::map definitions; 15 | auto root = Parser::to_schema(&definitions); 16 | return Definition{.root_ = root, .definitions_ = definitions}; 17 | } 18 | 19 | } // namespace rfl::parsing::schema 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/parsing/schemaful/tuple_to_object.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_PARSING_SCHEMAFUL_TUPLETOOBJECT_HPP_ 2 | #define RFL_PARSING_SCHEMAFUL_TUPLETOOBJECT_HPP_ 3 | 4 | #include 5 | 6 | #include "../schema/Type.hpp" 7 | 8 | namespace rfl::parsing::schemaful { 9 | 10 | /// Schemaful formats often don't have an explicit tuple representation. 11 | /// This is the required workaround. 12 | schema::Type::Object tuple_to_object(const schema::Type::Tuple& _tup); 13 | 14 | } // namespace rfl::parsing::schemaful 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/rfl/remove_fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_REMOVEFIELDS_HPP_ 2 | #define RFL_REMOVEFIELDS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "internal/StringLiteral.hpp" 9 | #include "internal/remove_fields.hpp" 10 | 11 | namespace rfl { 12 | 13 | /// Recursively removes all of the fields signified by _names from the 14 | /// NamedTupleType. 15 | template 16 | using remove_fields_t = 17 | typename internal::remove_fields, 18 | _names...>::type; 19 | 20 | } // namespace rfl 21 | 22 | #endif // RFL_REMOVEFIELDS_HPP_ 23 | -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "details/optional.hpp" 3 | #include "details/string_view.hpp" 4 | #include "details/generate_arrays.hpp" 5 | 6 | #include "algorithms.hpp" 7 | #include "array.hpp" 8 | #include "bitflags.hpp" 9 | #include "bitwise_operators.hpp" 10 | #include "enchantum.hpp" 11 | #include "entries.hpp" 12 | #include "iostream.hpp" 13 | #include "next_value.hpp" 14 | #include "bitset.hpp" 15 | 16 | #if __has_include() 17 | #include "fmt_format.hpp" 18 | #elif __has_include() 19 | #include "std_format.hpp" 20 | #endif -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/details/optional.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ENCHANTUM_CONFIG_FILE 4 | #include ENCHANTUM_CONFIG_FILE 5 | #endif 6 | 7 | #ifndef ENCHANTUM_ALIAS_OPTIONAL 8 | #include 9 | #endif 10 | 11 | 12 | namespace enchantum { 13 | #ifdef ENCHANTUM_ALIAS_OPTIONAL 14 | ENCHANTUM_ALIAS_OPTIONAL; 15 | #else 16 | using ::std::optional; 17 | #endif 18 | 19 | } // namespace enchantum -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/details/string_view.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #ifdef ENCHANTUM_CONFIG_FILE 5 | #include ENCHANTUM_CONFIG_FILE 6 | #endif 7 | 8 | #ifndef ENCHANTUM_ALIAS_STRING_VIEW 9 | #include 10 | #endif 11 | 12 | 13 | namespace enchantum { 14 | #ifdef ENCHANTUM_ALIAS_STRING_VIEW 15 | ENCHANTUM_ALIAS_STRING_VIEW; 16 | #else 17 | using ::std::string_view; 18 | #endif 19 | 20 | } // namespace enchantum -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/fmt_format.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bitflags.hpp" 4 | #include "details/format_util.hpp" 5 | #include "enchantum.hpp" 6 | #include 7 | 8 | template 9 | struct fmt::formatter : fmt::formatter { 10 | template 11 | constexpr auto format(const E e, FmtContext& ctx) const 12 | { 13 | return fmt::formatter::format(enchantum::details::format(e), ctx); 14 | } 15 | }; -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/iostream.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "istream.hpp" 3 | #include "ostream.hpp" 4 | 5 | namespace enchantum::iostream_operators { 6 | using ::enchantum::istream_operators::operator>>; 7 | using ::enchantum::ostream_operators::operator<<; 8 | } // namespace enchantum::iostream_operators -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/ostream.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "enchantum.hpp" 4 | #include 5 | #include 6 | #include "details/format_util.hpp" 7 | 8 | namespace enchantum::ostream_operators { 9 | template 10 | std::basic_ostream& operator<<(std::basic_ostream& os, const E e) 11 | { 12 | return os << details::format(e); 13 | } 14 | } // namespace enchantum::ostream_operators -------------------------------------------------------------------------------- /include/rfl/thirdparty/enchantum/std_format.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bitflags.hpp" 4 | #include "enchantum.hpp" 5 | 6 | #include 7 | #include 8 | #include "details/format_util.hpp" 9 | 10 | template 11 | struct std::formatter : std::formatter { 12 | template 13 | constexpr auto format(const E e, FmtContext& ctx) const 14 | { 15 | return std::formatter::format(enchantum::details::format(e), ctx); 16 | } 17 | }; -------------------------------------------------------------------------------- /include/rfl/to_generic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TO_GENERIC_HPP_ 2 | #define RFL_TO_GENERIC_HPP_ 3 | 4 | #include "Generic.hpp" 5 | #include "generic/write.hpp" 6 | 7 | namespace rfl { 8 | 9 | /// Generates a generic that is equivalent to the struct _t. 10 | template 11 | Generic to_generic(const auto& _t) { 12 | return rfl::generic::write(_t); 13 | } 14 | 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/to_view.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TO_VIEW_HPP_ 2 | #define RFL_TO_VIEW_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "internal/to_ptr_named_tuple.hpp" 10 | 11 | namespace rfl { 12 | 13 | template 14 | auto to_view(T& _t) { 15 | return internal::to_ptr_named_tuple(_t); 16 | } 17 | 18 | } // namespace rfl 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/toml.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TOML_HPP_ 2 | #define RFL_TOML_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "toml/Parser.hpp" 6 | #include "toml/Reader.hpp" 7 | #include "toml/Writer.hpp" 8 | #include "toml/load.hpp" 9 | #include "toml/read.hpp" 10 | #include "toml/save.hpp" 11 | #include "toml/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/toml/Parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TOML_PARSER_HPP_ 2 | #define RFL_TOML_PARSER_HPP_ 3 | 4 | #include "../parsing/Parser.hpp" 5 | #include "Reader.hpp" 6 | #include "Writer.hpp" 7 | 8 | namespace rfl::toml { 9 | 10 | template 11 | using Parser = parsing::Parser; 12 | 13 | } // namespace rfl::toml 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/rfl/toml/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TOML_LOAD_HPP_ 2 | #define RFL_TOML_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_string.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl::toml { 9 | 10 | template 11 | Result load(const std::string& _fname) { 12 | const auto read_string = [](const auto& _str) { 13 | return read(_str); 14 | }; 15 | return rfl::io::load_string(_fname).and_then(read_string); 16 | } 17 | 18 | } // namespace rfl::toml 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rfl/toml/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TOML_SAVE_HPP_ 2 | #define RFL_TOML_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_string.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl { 13 | namespace toml { 14 | 15 | template 16 | Result save(const std::string& _fname, const auto& _obj) { 17 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 18 | return write(_obj, _stream); 19 | }; 20 | return rfl::io::save_string(_fname, _obj, write_func); 21 | } 22 | 23 | } // namespace toml 24 | } // namespace rfl 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/rfl/tuple_cat.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TUPLE_CAT_HPP_ 2 | #define RFL_TUPLE_CAT_HPP_ 3 | 4 | #include "Tuple.hpp" 5 | #include "internal/tuple/concat.hpp" 6 | 7 | namespace rfl { 8 | 9 | template 10 | auto tuple_cat(const Head& _head, const Tail&... _tail) { 11 | return internal::tuple::concat(_head, _tail...); 12 | } 13 | 14 | template 15 | auto tuple_cat(Head&& _head, Tail&&... _tail) { 16 | return internal::tuple::concat(std::forward(_head), 17 | std::forward(_tail)...); 18 | } 19 | 20 | inline auto tuple_cat() { return rfl::Tuple(); } 21 | 22 | } // namespace rfl 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/type_name_t.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_TYPE_NAME_T_HPP_ 2 | #define RFL_TYPE_NAME_T_HPP_ 3 | 4 | #include 5 | 6 | #include "Literal.hpp" 7 | #include "internal/get_type_name.hpp" 8 | 9 | namespace rfl { 10 | 11 | /// Returns a rfl::Literal containing the type name of T. 12 | template 13 | using type_name_t = rfl::Literal()>; 14 | 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/ubjson.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_UBJSON_HPP_ 2 | #define RFL_UBJSON_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "ubjson/Parser.hpp" 6 | #include "ubjson/Reader.hpp" 7 | #include "ubjson/Writer.hpp" 8 | #include "ubjson/load.hpp" 9 | #include "ubjson/read.hpp" 10 | #include "ubjson/save.hpp" 11 | #include "ubjson/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/ubjson/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_UBJSON_LOAD_HPP_ 2 | #define RFL_UBJSON_LOAD_HPP_ 3 | 4 | #include "../Processors.hpp" 5 | #include "../Result.hpp" 6 | #include "../io/load_bytes.hpp" 7 | #include "read.hpp" 8 | 9 | namespace rfl::ubjson { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_bytes = [](const auto& _bytes) { 14 | return read(_bytes); 15 | }; 16 | return rfl::io::load_bytes(_fname).and_then(read_bytes); 17 | } 18 | 19 | } // namespace rfl::ubjson 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/rfl/ubjson/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_UBJSON_SAVE_HPP_ 2 | #define RFL_UBJSON_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Result.hpp" 9 | #include "../io/save_bytes.hpp" 10 | #include "write.hpp" 11 | 12 | namespace rfl::ubjson { 13 | 14 | template 15 | Result save(const std::string& _fname, const auto& _obj) { 16 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 17 | return write(_obj, _stream); 18 | }; 19 | return rfl::io::save_bytes(_fname, _obj, write_func); 20 | } 21 | 22 | } // namespace rfl::ubjson 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/rfl/xml.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_XML_HPP_ 2 | #define RFL_XML_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "xml/Parser.hpp" 6 | #include "xml/Reader.hpp" 7 | #include "xml/Writer.hpp" 8 | #include "xml/load.hpp" 9 | #include "xml/read.hpp" 10 | #include "xml/save.hpp" 11 | #include "xml/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/xml/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_XML_LOAD_HPP_ 2 | #define RFL_XML_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_string.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace xml { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_string = [](const auto& _str) { 14 | return read(_str); 15 | }; 16 | return rfl::io::load_string(_fname).and_then(read_string); 17 | } 18 | 19 | } // namespace xml 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/yaml.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_YAML_HPP_ 2 | #define RFL_YAML_HPP_ 3 | 4 | #include "../rfl.hpp" 5 | #include "yaml/Parser.hpp" 6 | #include "yaml/Reader.hpp" 7 | #include "yaml/Writer.hpp" 8 | #include "yaml/load.hpp" 9 | #include "yaml/read.hpp" 10 | #include "yaml/save.hpp" 11 | #include "yaml/write.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/rfl/yaml/Parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_YAML_PARSER_HPP_ 2 | #define RFL_YAML_PARSER_HPP_ 3 | 4 | #include "../parsing/Parser.hpp" 5 | #include "Reader.hpp" 6 | #include "Writer.hpp" 7 | 8 | namespace rfl { 9 | namespace yaml { 10 | 11 | template 12 | using Parser = parsing::Parser; 13 | 14 | } 15 | } // namespace rfl 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/rfl/yaml/load.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_YAML_LOAD_HPP_ 2 | #define RFL_YAML_LOAD_HPP_ 3 | 4 | #include "../Result.hpp" 5 | #include "../io/load_string.hpp" 6 | #include "read.hpp" 7 | 8 | namespace rfl { 9 | namespace yaml { 10 | 11 | template 12 | Result load(const std::string& _fname) { 13 | const auto read_string = [](const auto& _str) { 14 | return read(_str); 15 | }; 16 | return rfl::io::load_string(_fname).and_then(read_string); 17 | } 18 | 19 | } // namespace yaml 20 | } // namespace rfl 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/rfl/yaml/save.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RFL_YAML_SAVE_HPP_ 2 | #define RFL_YAML_SAVE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../Processors.hpp" 9 | #include "../Result.hpp" 10 | #include "../io/save_string.hpp" 11 | #include "write.hpp" 12 | 13 | namespace rfl { 14 | namespace yaml { 15 | 16 | template 17 | Result save(const std::string& _fname, const auto& _obj) { 18 | const auto write_func = [](const auto& _obj, auto& _stream) -> auto& { 19 | return write(_obj, _stream); 20 | }; 21 | return rfl::io::save_string(_fname, _obj, write_func); 22 | } 23 | 24 | } // namespace yaml 25 | } // namespace rfl 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "reflect-cpp" 3 | version = "0.14.1" 4 | 5 | [tool.hatch.envs.default] 6 | dependencies = [ 7 | "mkdocs~=1.6", 8 | "mkdocs-material~=9.5", 9 | "mkdocs-htmlproofer-plugin~=1.2", 10 | ] 11 | 12 | [tool.hatch.envs.insiders] 13 | dependencies = [ 14 | "mkdocs~=1.6", 15 | "mkdocs-material @ git+https://{env:GH_C17_DEV_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.39-insiders-4.53.14", 16 | "mkdocs-htmlproofer-plugin~=1.2", 17 | ] -------------------------------------------------------------------------------- /src/rfl/capnproto/Reader.cpp: -------------------------------------------------------------------------------- 1 | #include "rfl/capnproto/Reader.hpp" 2 | 3 | #include "rfl/parsing/schemaful/IsSchemafulReader.hpp" 4 | 5 | namespace rfl::capnproto { 6 | 7 | static_assert(parsing::schemaful::IsSchemafulReader, 8 | "This must be a schemaful reader."); 9 | 10 | std::optional> 11 | Reader::identify_discriminant(const InputUnionType& _union) const noexcept { 12 | size_t ix = 0; 13 | for (auto field : _union.val_.getSchema().getFields()) { 14 | if (_union.val_.has(field)) { 15 | return std::make_pair(field, ix); 16 | } 17 | ++ix; 18 | } 19 | return std::optional>(); 20 | } 21 | 22 | } // namespace rfl::capnproto 23 | -------------------------------------------------------------------------------- /src/rfl/parsing/schemaful/tuple_to_object.cpp: -------------------------------------------------------------------------------- 1 | #include "rfl/parsing/schemaful/tuple_to_object.hpp" 2 | 3 | namespace rfl::parsing::schemaful { 4 | 5 | std::string to_field_name(const size_t _i) { 6 | return std::string({'f', static_cast('0' + ((_i / 100) % 10)), 7 | static_cast('0' + ((_i / 10) % 10)), 8 | static_cast('0' + (_i % 10))}); 9 | } 10 | 11 | schema::Type::Object tuple_to_object(const schema::Type::Tuple& _tup) { 12 | auto obj = schema::Type::Object{}; 13 | for (size_t i = 0; i < _tup.types_.size(); ++i) { 14 | obj.types_[to_field_name(i)] = _tup.types_[i]; 15 | } 16 | return obj; 17 | } 18 | } // namespace rfl::parsing::schemaful 19 | -------------------------------------------------------------------------------- /tests/avro/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-avro-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-avro-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-avro-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | 12 | target_link_libraries( 13 | reflect-cpp-avro-tests 14 | PRIVATE 15 | "${REFLECT_CPP_GTEST_LIB}" 16 | ) 17 | 18 | find_package(GTest) 19 | gtest_discover_tests(reflect-cpp-avro-tests) 20 | -------------------------------------------------------------------------------- /tests/avro/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | }; 13 | 14 | TEST(avro, test_bytestring) { 15 | const auto test = 16 | TestStruct{.bytestring = rfl::Bytestring({std::byte{13}, std::byte{14}, 17 | std::byte{15}, std::byte{16}})}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_bytestring 22 | -------------------------------------------------------------------------------- /tests/avro/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(avro, test_enum) { 20 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 21 | 22 | write_and_read(circle); 23 | } 24 | 25 | } // namespace test_enum 26 | -------------------------------------------------------------------------------- /tests/avro/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_literal { 11 | 12 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 13 | using LastName = rfl::Literal<"Simpson">; 14 | 15 | struct Person { 16 | rfl::Rename<"firstName", FirstName> first_name; 17 | rfl::Rename<"lastName", LastName> last_name; 18 | std::vector children; 19 | }; 20 | 21 | TEST(avro, test_literal) { 22 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 23 | 24 | write_and_read(bart); 25 | } 26 | } // namespace test_literal 27 | -------------------------------------------------------------------------------- /tests/avro/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(avro, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/avro/test_rfl_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::Variant>; 25 | 26 | TEST(avro, test_rfl_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/avro/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(avro, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/avro/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_string_map { 11 | TEST(avro, test_string_map) { 12 | std::map> homer; 13 | homer.insert( 14 | std::make_pair("firstName", std::make_unique("Homer"))); 15 | homer.insert( 16 | std::make_pair("lastName", std::make_unique("Simpson"))); 17 | 18 | write_and_read(homer); 19 | } 20 | } // namespace test_string_map 21 | -------------------------------------------------------------------------------- /tests/avro/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Rectangle, Circle, Square>; 25 | 26 | TEST(avro, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/avro/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(avro, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/avro/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(avro, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/avro/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::avro::write(_struct); 14 | const auto res = rfl::avro::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::avro::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/bson/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-bson-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-bson-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-bson-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-bson-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-bson-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-bson-tests) 21 | -------------------------------------------------------------------------------- /tests/bson/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | std::vector bytestrings; 13 | }; 14 | 15 | TEST(bson, test_bytestring) { 16 | const auto bstr = rfl::Bytestring( 17 | {std::byte{13}, std::byte{14}, std::byte{15}, std::byte{16}}); 18 | const auto test = TestStruct{ 19 | .bytestring = bstr, 20 | .bytestrings = std::vector({bstr, bstr, bstr})}; 21 | write_and_read(test); 22 | } 23 | } // namespace test_bytestring 24 | -------------------------------------------------------------------------------- /tests/bson/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(bson, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/bson/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(bson, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/bson/test_oid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_oid { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | std::vector oids; 14 | }; 15 | 16 | void test() { 17 | #ifdef REFLECT_CPP_C_ARRAYS_OR_INHERITANCE 18 | auto oids = std::vector(3); 19 | 20 | for (auto& oid : oids) { 21 | bson_oid_init(&oid, NULL); 22 | } 23 | 24 | const auto homer = 25 | Person{.first_name = "Homer", .last_name = "Simpson", .oids = oids}; 26 | 27 | write_and_read(homer); 28 | #endif 29 | } 30 | } // namespace test_oid 31 | -------------------------------------------------------------------------------- /tests/bson/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(bson, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/bson/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(bson, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/bson/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(bson, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/bson/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(bson, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/bson/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(bson, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/bson/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(bson, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/bson/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::bson::write(_struct); 14 | const auto res = rfl::bson::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::bson::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tests/capnproto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-capnproto-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-capnproto-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-capnproto-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | 12 | target_link_libraries( 13 | reflect-cpp-capnproto-tests 14 | PRIVATE 15 | "${REFLECT_CPP_GTEST_LIB}" 16 | ) 17 | 18 | find_package(GTest) 19 | gtest_discover_tests(reflect-cpp-capnproto-tests) 20 | -------------------------------------------------------------------------------- /tests/capnproto/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | }; 13 | 14 | TEST(capnproto, test_bytestring) { 15 | const auto test = 16 | TestStruct{.bytestring = rfl::Bytestring({std::byte{13}, std::byte{14}, 17 | std::byte{15}, std::byte{16}})}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_bytestring 22 | -------------------------------------------------------------------------------- /tests/capnproto/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(capnproto, test_enum) { 20 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 21 | 22 | write_and_read(circle); 23 | } 24 | 25 | } // namespace test_enum 26 | -------------------------------------------------------------------------------- /tests/capnproto/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_literal { 11 | 12 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 13 | using LastName = rfl::Literal<"Simpson">; 14 | 15 | struct Person { 16 | rfl::Rename<"firstName", FirstName> first_name; 17 | rfl::Rename<"lastName", LastName> last_name; 18 | std::vector children; 19 | }; 20 | 21 | TEST(capnproto, test_literal) { 22 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 23 | 24 | write_and_read(bart); 25 | } 26 | } // namespace test_literal 27 | -------------------------------------------------------------------------------- /tests/capnproto/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(capnproto, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/capnproto/test_rfl_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | struct Shapes { 25 | rfl::Variant> root; 26 | }; 27 | 28 | TEST(capnproto, test_rfl_variant) { 29 | const auto r = Shapes{Rectangle{.height = 10, .width = 5}}; 30 | 31 | write_and_read(r); 32 | } 33 | } // namespace test_variant 34 | -------------------------------------------------------------------------------- /tests/capnproto/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(capnproto, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/capnproto/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_string_map { 11 | 12 | struct RootStruct { 13 | std::map> root; 14 | }; 15 | 16 | TEST(capnproto, test_string_map) { 17 | RootStruct homer; 18 | homer.root.insert( 19 | std::make_pair("firstName", std::make_unique("Homer"))); 20 | homer.root.insert( 21 | std::make_pair("lastName", std::make_unique("Simpson"))); 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_string_map 26 | -------------------------------------------------------------------------------- /tests/capnproto/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | struct Shapes { 25 | rfl::TaggedUnion<"shape", Rectangle, Circle, Square> root; 26 | }; 27 | 28 | TEST(capnproto, test_tagged_union) { 29 | const auto r = Shapes{Rectangle{.height = 10, .width = 5}}; 30 | write_and_read(r); 31 | } 32 | } // namespace test_tagged_union 33 | -------------------------------------------------------------------------------- /tests/capnproto/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | struct Shapes { 25 | std::variant> root; 26 | }; 27 | 28 | TEST(capnproto, test_variant) { 29 | const auto r = Shapes{Rectangle{.height = 10, .width = 5}}; 30 | 31 | write_and_read(r); 32 | } 33 | } // namespace test_variant 34 | -------------------------------------------------------------------------------- /tests/capnproto/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(capnproto, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/capnproto/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::capnproto::write(_struct); 14 | const auto res = rfl::capnproto::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::capnproto::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/cbor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-cbor-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-cbor-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-cbor-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_link_libraries( 12 | reflect-cpp-cbor-tests 13 | PRIVATE 14 | "${REFLECT_CPP_GTEST_LIB}" 15 | ) 16 | 17 | find_package(GTest) 18 | gtest_discover_tests(reflect-cpp-cbor-tests) 19 | 20 | -------------------------------------------------------------------------------- /tests/cbor/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | }; 13 | 14 | TEST(cbor, test_bytestring) { 15 | const auto test = 16 | TestStruct{.bytestring = rfl::Bytestring({std::byte{13}, std::byte{14}, 17 | std::byte{15}, std::byte{16}})}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_bytestring 22 | -------------------------------------------------------------------------------- /tests/cbor/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(cbor, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/cbor/test_extra_fields.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_extra_fields { 10 | 11 | struct Person { 12 | rfl::Rename<"firstName", std::string> first_name; 13 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 14 | rfl::ExtraFields extra_fields; 15 | }; 16 | 17 | TEST(cbor, test_extra_fields) { 18 | auto homer = Person{.first_name = "Homer"}; 19 | 20 | homer.extra_fields["age"] = 45; 21 | homer.extra_fields["email"] = "homer@simpson.com"; 22 | homer.extra_fields["town"] = "Springfield"; 23 | 24 | write_and_read(homer); 25 | } 26 | } // namespace test_extra_fields 27 | -------------------------------------------------------------------------------- /tests/cbor/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(cbor, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/cbor/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(cbor, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/cbor/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(cbor, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/cbor/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(cbor, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/cbor/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(cbor, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/cbor/test_tagged_union2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union2 { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(cbor, test_tagged_union2) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union2 31 | -------------------------------------------------------------------------------- /tests/cbor/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(cbor, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/cbor/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(cbor, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/cbor/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::cbor::write(_struct); 14 | const auto res = rfl::cbor::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::cbor::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/flexbuffers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-flexbuffers-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-flexbuffers-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-flexbuffers-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-flexbuffers-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-flexbuffers-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-flexbuffers-tests) 21 | 22 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | std::vector bytestrings; 13 | }; 14 | 15 | TEST(flexbuf, test_bytestring) { 16 | const auto bstr = rfl::Bytestring( 17 | {std::byte{13}, std::byte{14}, std::byte{15}, std::byte{16}}); 18 | const auto test = TestStruct{ 19 | .bytestring = bstr, 20 | .bytestrings = std::vector({bstr, bstr, bstr})}; 21 | write_and_read(test); 22 | } 23 | } // namespace test_bytestring 24 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(flexbuf, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(flexbuf, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(flexbuf, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "write_and_read.hpp" 5 | 6 | namespace test_set { 7 | 8 | struct Person { 9 | rfl::Rename<"firstName", std::string> first_name; 10 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 11 | std::unique_ptr> children; 12 | }; 13 | 14 | TEST(flexbuf, test_set) { 15 | auto children = std::make_unique>( 16 | std::set({"Bart", "Lisa", "Maggie"})); 17 | 18 | const auto homer = 19 | Person{.first_name = "Homer", .children = std::move(children)}; 20 | 21 | write_and_read(homer); 22 | } 23 | } // namespace test_set 24 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(flexbuf, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(flexbuf, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_tagged_union2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union2 { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(flexbuf, test_tagged_union2) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union2 31 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(flexbuf, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/flexbuffers/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(flexbuf, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/flexbuffers/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::flexbuf::write(_struct); 14 | const auto res = rfl::flexbuf::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::flexbuf::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tests/generic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-generic-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-generic-tests 7 | ${SOURCES} 8 | ) 9 | 10 | target_include_directories(reflect-cpp-generic-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 11 | 12 | target_link_libraries( 13 | reflect-cpp-generic-tests 14 | PRIVATE 15 | "${REFLECT_CPP_GTEST_LIB}" 16 | ) 17 | 18 | find_package(GTest) 19 | gtest_discover_tests(reflect-cpp-generic-tests) 20 | 21 | -------------------------------------------------------------------------------- /tests/generic/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_enum { 9 | 10 | enum class Color { red, green, blue, yellow }; 11 | enum Location { left, centre, right }; // Unscoped enum 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | Location location; 17 | }; 18 | 19 | TEST(generic, test_enum) { 20 | const auto circle = 21 | Circle{.radius = 2.0, .color = Color::green, .location = centre}; 22 | 23 | write_and_read(circle); 24 | } 25 | 26 | } // namespace test_enum 27 | -------------------------------------------------------------------------------- /tests/generic/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(generic, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/generic/test_optional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace test_optional { 6 | 7 | struct Person { 8 | std::string name; 9 | std::optional> spouse; 10 | }; 11 | 12 | TEST(generic, test_optional) { 13 | rfl::Generic generic; 14 | // This failed to compile due to optional copying rather than moving 15 | rfl::from_generic(generic); 16 | } 17 | } // namespace test_map 18 | -------------------------------------------------------------------------------- /tests/generic/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(generic, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/generic/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(generic, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/generic/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(generic, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/generic/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(generic, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/generic/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(generic, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/generic/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(generic, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/json/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-json-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-json-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-json-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-json-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-json-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-json-tests) 21 | 22 | -------------------------------------------------------------------------------- /tests/json/test_alphanumeric_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_alphanumeric_map { 10 | 11 | TEST(json, test_alphanumeric_map) { 12 | std::map> homer; 13 | homer.insert( 14 | std::make_pair("firstName", std::make_unique("Homer"))); 15 | homer.insert( 16 | std::make_pair("lastName", std::make_unique("Simpson"))); 17 | 18 | write_and_read(homer, R"({"firstName":"Homer","lastName":"Simpson"})"); 19 | } 20 | 21 | } // namespace test_alphanumeric_map 22 | -------------------------------------------------------------------------------- /tests/json/test_array2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_array2 { 9 | 10 | struct Foo { 11 | std::array v; 12 | }; 13 | 14 | struct Bar { 15 | std::array v; 16 | }; 17 | 18 | using FooBar = std::variant; // or rfl::Variant 19 | 20 | TEST(json, test_array2) { 21 | FooBar foobar = Bar({1, 2, 3}); 22 | 23 | write_and_read(foobar, R"({"v":[1,2,3]})"); 24 | } 25 | } // namespace test_array2 26 | -------------------------------------------------------------------------------- /tests/json/test_binary.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_binary { 10 | 11 | struct TestStruct { 12 | rfl::Binary binary; 13 | }; 14 | 15 | TEST(json, test_binary) { 16 | const auto test = TestStruct{.binary = 30}; 17 | write_and_read(test, R"({"binary":"00011110"})"); 18 | } 19 | } // namespace test_binary 20 | -------------------------------------------------------------------------------- /tests/json/test_box2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace test_box2 { 9 | 10 | TEST(json, test_box2) { 11 | auto ptr = std::make_unique("Hello World!"); 12 | const rfl::Result> box = 13 | rfl::make_box(std::move(ptr)); 14 | 15 | ASSERT_TRUE(box && true); 16 | } 17 | } // namespace test_box2 18 | -------------------------------------------------------------------------------- /tests/json/test_default_if_missing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_default_if_missing { 10 | 11 | struct Person { 12 | std::string first_name; 13 | std::string last_name = "Simpson"; 14 | std::string town; 15 | }; 16 | 17 | TEST(json, test_default_if_missing) { 18 | auto homer = rfl::json::read( 19 | R"({"first_name":"Homer"})") 20 | .value(); 21 | 22 | EXPECT_EQ(homer.first_name, "Homer"); 23 | EXPECT_EQ(homer.last_name, "Simpson"); 24 | EXPECT_EQ(homer.town, ""); 25 | } 26 | } // namespace test_default_if_missing 27 | -------------------------------------------------------------------------------- /tests/json/test_duration.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_duration { 10 | 11 | struct TestStruct { 12 | std::chrono::seconds duration; 13 | }; 14 | 15 | TEST(json, test_duration) { 16 | const auto test = TestStruct{.duration = std::chrono::seconds(10)}; 17 | write_and_read(test, R"({"duration":{"count":10,"unit":"seconds"}})"); 18 | } 19 | } // namespace test_duration 20 | -------------------------------------------------------------------------------- /tests/json/test_duration_conversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_duration_conversion { 10 | 11 | struct TestStruct1 { 12 | std::chrono::minutes duration; 13 | }; 14 | 15 | struct TestStruct2 { 16 | std::chrono::seconds duration; 17 | }; 18 | 19 | TEST(json, test_duration_conversion) { 20 | const auto test1 = TestStruct1{.duration = std::chrono::minutes(10)}; 21 | const auto test2 = 22 | rfl::json::read(rfl::json::write(test1)).value(); 23 | write_and_read(test2, R"({"duration":{"count":600,"unit":"seconds"}})"); 24 | } 25 | } // namespace test_duration_conversion 26 | -------------------------------------------------------------------------------- /tests/json/test_email.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_email { 10 | 11 | struct Person { 12 | rfl::Rename<"firstName", std::string> first_name; 13 | rfl::Rename<"lastName", std::string> last_name; 14 | rfl::Email email; 15 | }; 16 | 17 | TEST(json, test_email) { 18 | const auto homer = Person{.first_name = "Homer", 19 | .last_name = "Simpson", 20 | .email = "homer@simpson.com"}; 21 | 22 | write_and_read( 23 | homer, 24 | R"({"firstName":"Homer","lastName":"Simpson","email":"homer@simpson.com"})"); 25 | } 26 | } // namespace test_email 27 | -------------------------------------------------------------------------------- /tests/json/test_empty_object.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_empty_object { 10 | 11 | struct Empty {}; 12 | 13 | TEST(json, test_empty_object) { 14 | const auto empty = Empty{}; 15 | 16 | write_and_read(empty, R"({})"); 17 | } 18 | } // namespace test_empty_object 19 | -------------------------------------------------------------------------------- /tests/json/test_enum1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum1 { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(json, test_enum1) { 20 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 21 | 22 | write_and_read(circle, R"({"radius":2.0,"color":"green"})"); 23 | } 24 | 25 | } // namespace test_enum1 26 | -------------------------------------------------------------------------------- /tests/json/test_enum2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum2 { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(json, test_enum2) { 20 | auto mutable_circle = Circle{.radius = 2.0, .color = Color::green}; 21 | 22 | if (auto color = rfl::string_to_enum("red"); color) { 23 | mutable_circle.color = *color; 24 | } 25 | write_and_read(mutable_circle, R"({"radius":2.0,"color":"red"})"); 26 | } 27 | 28 | } // namespace test_enum2 29 | -------------------------------------------------------------------------------- /tests/json/test_enum3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum3 { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(json, test_enum3) { 20 | auto mutable_circle = Circle{.radius = 2.0, .color = Color::red}; 21 | 22 | if (auto color = rfl::string_to_enum("bart"); color) { 23 | mutable_circle.color = *color; 24 | } 25 | write_and_read(mutable_circle, R"({"radius":2.0,"color":"red"})"); 26 | } 27 | 28 | } // namespace test_enum3 29 | -------------------------------------------------------------------------------- /tests/json/test_enum4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_enum4 { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(json, test_enum4) { 20 | 21 | auto mutable_circle = Circle{.radius = 2.0, .color = Color::red}; 22 | 23 | if (auto color = rfl::string_to_enum(rfl::enum_to_string(Color::blue)); 24 | color) { 25 | mutable_circle.color = *color; 26 | } 27 | 28 | write_and_read(mutable_circle, R"({"radius":2.0,"color":"blue"})"); 29 | } 30 | 31 | } // namespace test_enum4 32 | -------------------------------------------------------------------------------- /tests/json/test_filepath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_filepath { 11 | 12 | struct Person { 13 | rfl::Rename<"firstName", std::string> first_name; 14 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 15 | std::filesystem::path path; 16 | }; 17 | 18 | TEST(json, test_filepath) { 19 | auto homer = 20 | Person{.first_name = "Homer", .path = "/usr/lib/homer_simpson.cf"}; 21 | 22 | write_and_read( 23 | homer, 24 | R"({"firstName":"Homer","lastName":"Simpson","path":"/usr/lib/homer_simpson.cf"})"); 25 | } 26 | } // namespace test_filepath 27 | -------------------------------------------------------------------------------- /tests/json/test_generic2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_generic2 { 11 | 12 | TEST(json, test_generic2) { 13 | std::string response = 14 | "{\"kind\":2,\"error\":\"Internal " 15 | "error\",\"status\":101,\"stats\":{\"cpuTime\":803,\"totalTime\":1}}"; 16 | 17 | struct DataHolder { 18 | int kind = 0; 19 | rfl::Generic data; 20 | }; 21 | auto result = rfl::json::read(response); 22 | 23 | EXPECT_TRUE(!(result && true)); 24 | } 25 | 26 | } // namespace test_generic2 27 | -------------------------------------------------------------------------------- /tests/json/test_hex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_hex { 10 | 11 | struct TestStruct { 12 | rfl::Hex hex; 13 | }; 14 | 15 | TEST(json, test_hex) { 16 | const auto test = TestStruct{.hex = 30}; 17 | write_and_read(test, R"({"hex":"1e"})"); 18 | } 19 | } // namespace test_hex 20 | -------------------------------------------------------------------------------- /tests/json/test_integers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_integers { 8 | 9 | TEST(json, test_integers) { 10 | 11 | struct Integers { 12 | int i32; 13 | unsigned int u32; 14 | long long i64; 15 | unsigned long long u64; 16 | }; 17 | 18 | write_and_read(Integers{.i32 = INT32_MAX, .u32 = UINT32_MAX, .i64 = INT64_MAX, .u64 = UINT64_MAX}, R"({"i32":2147483647,"u32":4294967295,"i64":9223372036854775807,"u64":18446744073709551615})"); 19 | write_and_read(Integers{.i32 = INT32_MIN, .u32 = 0, .i64 = INT64_MIN, .u64 = 0}, R"({"i32":-2147483648,"u32":0,"i64":-9223372036854775808,"u64":0})"); 20 | } 21 | 22 | } // namespace test_integers 23 | -------------------------------------------------------------------------------- /tests/json/test_meta_fields.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace test_meta_fields { 7 | 8 | struct Person { 9 | std::string first_name; 10 | std::string last_name = "Simpson"; 11 | std::string town = "Springfield"; 12 | unsigned int age; 13 | std::vector children; 14 | }; 15 | 16 | TEST(json, test_meta_fields) { 17 | const auto fields = rfl::fields(); 18 | 19 | EXPECT_EQ(fields.size(), 5); 20 | } 21 | } // namespace test_meta_fields 22 | -------------------------------------------------------------------------------- /tests/json/test_movable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | 11 | struct MoveableType { 12 | int x; 13 | 14 | 15 | MoveableType(MoveableType&&) = default; 16 | MoveableType(const MoveableType&) = delete; 17 | 18 | using ReflectionType = int; 19 | MoveableType(int&& x) : x(x) {} 20 | int reflection() const { return x; } 21 | }; 22 | 23 | TEST(json, test_moveable) { 24 | MoveableType moveable = {2}; 25 | 26 | write_and_read( 27 | moveable, R"(2)"); 28 | } -------------------------------------------------------------------------------- /tests/json/test_named_tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_named_tuple { 10 | 11 | TEST(json, test_named_tuple) { 12 | const auto homer = rfl::make_field<"firstName", std::string>("Homer") * 13 | rfl::make_field<"lastName", std::string>("Simpson") * 14 | rfl::make_field<"age">(45); 15 | 16 | write_and_read(homer, 17 | R"({"firstName":"Homer","lastName":"Simpson","age":45})"); 18 | } 19 | } // namespace test_named_tuple 20 | -------------------------------------------------------------------------------- /tests/json/test_no_extra_fields.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_no_extra_fields { 10 | 11 | struct Person { 12 | std::string first_name; 13 | std::string last_name = "Simpson"; 14 | }; 15 | 16 | TEST(json, test_no_extra_fields) { 17 | auto homer = rfl::json::read( 18 | R"({"first_name":"Homer","last_name":"Simpson","extra_field":0})"); 19 | 20 | EXPECT_EQ(homer && true, false); 21 | } 22 | } // namespace test_no_extra_fields 23 | -------------------------------------------------------------------------------- /tests/json/test_no_extra_fields_with_default.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_no_extra_fields_with_default { 10 | 11 | struct Person { 12 | std::string first_name; 13 | std::string last_name = "Simpson"; 14 | }; 15 | 16 | TEST(json, test_no_extra_fields_with_default) { 17 | auto homer = 18 | rfl::json::read( 19 | R"({"first_name":"Homer","last_name":"Simpson","extra_field":0})"); 20 | 21 | EXPECT_EQ(homer && true, false); 22 | } 23 | } // namespace test_no_extra_fields_with_default 24 | -------------------------------------------------------------------------------- /tests/json/test_object.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_object { 9 | 10 | TEST(json, test_object) { 11 | rfl::Object o; 12 | o["hello"] = "world"; 13 | EXPECT_EQ(o.get("hello").value().to_string().value(), "world"); 14 | EXPECT_EQ(o.at("hello").to_string().value(), "world"); 15 | } 16 | 17 | } // namespace test_object 18 | -------------------------------------------------------------------------------- /tests/json/test_oct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_oct { 10 | 11 | struct TestStruct { 12 | rfl::Oct oct; 13 | }; 14 | 15 | TEST(json, test_oct) { 16 | const auto test = TestStruct{.oct = 30}; 17 | write_and_read(test, R"({"oct":"36"})"); 18 | } 19 | } // namespace test_oct 20 | -------------------------------------------------------------------------------- /tests/json/test_rfl_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_rfl_variant { 11 | 12 | struct Circle { 13 | double radius; 14 | }; 15 | 16 | struct Rectangle { 17 | double height; 18 | double width; 19 | }; 20 | 21 | struct Square { 22 | double width; 23 | }; 24 | 25 | using Shapes = rfl::Variant>; 26 | 27 | TEST(json, test_rfl_variant) { 28 | const Shapes r = Rectangle{.height = 10, .width = 5}; 29 | 30 | write_and_read(r, R"({"height":10.0,"width":5.0})"); 31 | } 32 | } // namespace test_rfl_variant 33 | -------------------------------------------------------------------------------- /tests/json/test_rfl_variant_emplace.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_rfl_variant_emplace { 11 | 12 | struct Circle { 13 | double radius; 14 | }; 15 | 16 | struct Rectangle { 17 | double height; 18 | double width; 19 | }; 20 | 21 | struct Square { 22 | double width; 23 | }; 24 | 25 | using Shapes = rfl::Variant>; 26 | 27 | TEST(json, test_rfl_variant_emplace) { 28 | Shapes r; 29 | r.emplace<1>(10.0, 5.0); 30 | write_and_read(r, R"({"height":10.0,"width":5.0})"); 31 | } 32 | } // namespace test_rfl_variant_emplace 33 | -------------------------------------------------------------------------------- /tests/json/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_string_map { 11 | TEST(json, test_string_map) { 12 | std::map> homer; 13 | homer.insert( 14 | std::make_pair("firstName", std::make_unique("Homer"))); 15 | homer.insert( 16 | std::make_pair("lastName", std::make_unique("Simpson"))); 17 | 18 | write_and_read(homer, R"({"firstName":"Homer","lastName":"Simpson"})"); 19 | } 20 | } // namespace test_string_map 21 | -------------------------------------------------------------------------------- /tests/json/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_tagged_union { 11 | 12 | struct Circle { 13 | double radius; 14 | }; 15 | 16 | struct Rectangle { 17 | double height; 18 | double width; 19 | }; 20 | 21 | struct Square { 22 | double width; 23 | }; 24 | 25 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 26 | 27 | TEST(json, test_tagged_union) { 28 | const Shapes r = Rectangle{.height = 10, .width = 5}; 29 | 30 | write_and_read(r, R"({"shape":"Rectangle","height":10.0,"width":5.0})"); 31 | } 32 | } // namespace test_tagged_union 33 | -------------------------------------------------------------------------------- /tests/json/test_tagged_union4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_tagged_union4 { 11 | 12 | struct Circle { 13 | double radius; 14 | }; 15 | 16 | struct Rectangle { 17 | double height; 18 | double width; 19 | }; 20 | 21 | struct Square { 22 | double width; 23 | }; 24 | 25 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 26 | 27 | TEST(json, test_tagged_union4) { 28 | const Shapes r = Rectangle{.height = 10, .width = 5}; 29 | 30 | write_and_read(r, R"(["Rectangle",10.0,5.0])"); 31 | } 32 | } // namespace test_tagged_union4 33 | -------------------------------------------------------------------------------- /tests/json/test_template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_template { 10 | 11 | template 12 | struct A { 13 | int code; 14 | std::string msg; 15 | T data; 16 | }; 17 | 18 | struct B { 19 | int some_val; 20 | }; 21 | 22 | TEST(json, test_template) { 23 | const auto a = A{.code = 0, .msg = "hello", .data = B{.some_val = 1}}; 24 | 25 | write_and_read(a, R"({"code":0,"msg":"hello","data":{"some_val":1}})"); 26 | } 27 | 28 | } // namespace test_template 29 | -------------------------------------------------------------------------------- /tests/json/test_underlying_enums.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_underlying_enums { 11 | 12 | enum class Color { red, green, blue, yellow }; 13 | 14 | struct Circle { 15 | float radius; 16 | Color color; 17 | }; 18 | 19 | TEST(json, test_underlying_enums) { 20 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 21 | 22 | write_and_read(circle, R"({"radius":2.0,"color":1})"); 23 | } 24 | 25 | } // namespace test_enum1 26 | -------------------------------------------------------------------------------- /tests/json/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_variant { 11 | 12 | struct Circle { 13 | double radius; 14 | }; 15 | 16 | struct Rectangle { 17 | double height; 18 | double width; 19 | }; 20 | 21 | struct Square { 22 | double width; 23 | }; 24 | 25 | using Shapes = std::variant>; 26 | 27 | TEST(json, test_variant) { 28 | const Shapes r = Rectangle{.height = 10, .width = 5}; 29 | 30 | write_and_read(r, R"({"height":10.0,"width":5.0})"); 31 | } 32 | } // namespace test_variant 33 | -------------------------------------------------------------------------------- /tests/json/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_wstring { 11 | TEST(json, test_wstring) { 12 | std::map homer; 13 | homer.insert(std::make_pair("firstName", L"Homer")); 14 | 15 | write_and_read(homer, R"({"firstName":"Homer"})"); 16 | } 17 | } // namespace test_wstring 18 | -------------------------------------------------------------------------------- /tests/json_c_arrays_and_inheritance/test_c_array_class1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rfl.hpp" 4 | #include "rfl/json.hpp" 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_c_array_class1 { 8 | 9 | struct Test1 { 10 | std::vector classes[3]; 11 | }; 12 | 13 | TEST(json, test_inheritance2) { 14 | Test1 test1 = {.classes = {{"Little A", "Little B", "Little C"}, 15 | {"BIG A", "BIG B", "BIG C"}, 16 | {"??", "$%", "#@"}}}; 17 | write_and_read( 18 | test1, 19 | R"({"classes":[["Little A","Little B","Little C"],["BIG A","BIG B","BIG C"],["??","$%","#@"]]})"); 20 | } 21 | 22 | } // namespace test_c_array_class1 23 | -------------------------------------------------------------------------------- /tests/json_c_arrays_and_inheritance/test_c_array_class3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rfl.hpp" 4 | #include "rfl/json.hpp" 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_c_array_class3 { 8 | 9 | using Test3 = std::array[3]; 10 | 11 | TEST(json, test_c_array_class3) { 12 | Test3 test3 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; 13 | write_and_read(test3, "[[1,2,3],[4,5,6],[7,8,9]]"); 14 | } 15 | 16 | } // namespace test_c_array_class3 17 | -------------------------------------------------------------------------------- /tests/json_c_arrays_and_inheritance/test_c_array_class4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rfl.hpp" 4 | #include "rfl/json.hpp" 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_c_array_class4 { 8 | 9 | struct Test4 { 10 | int a[3]; 11 | int b[3]; 12 | int c[2][2]; 13 | }; 14 | 15 | TEST(json, test_c_array_class4) { 16 | Test4 test4 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}}; 17 | write_and_read(test4, R"({"a":[1,2,3],"b":[4,5,6],"c":[[7,8],[9,10]]})"); 18 | } 19 | 20 | } // namespace test_c_array_class4 21 | -------------------------------------------------------------------------------- /tests/json_c_arrays_and_inheritance/test_c_array_class5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rfl.hpp" 4 | #include "rfl/json.hpp" 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_c_array_class5 { 8 | 9 | struct Test5 { 10 | int a[3]; 11 | int b[3]; 12 | int c[2][2]; 13 | }; 14 | 15 | TEST(json, test_c_array_class5) { 16 | Test5 t1 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}}; 17 | const auto t2 = rfl::replace(t1, rfl::make_field<"b", int[3]>({1, 2, 3})); 18 | write_and_read(t2, R"({"a":[1,2,3],"b":[1,2,3],"c":[[7,8],[9,10]]})"); 19 | } 20 | 21 | } // namespace test_c_array_class5 22 | -------------------------------------------------------------------------------- /tests/json_c_arrays_and_inheritance/test_inheritance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace test_inheritance { 9 | 10 | TEST(json, test_inheritance) { 11 | struct S { 12 | int x; 13 | }; 14 | 15 | struct T : S {}; 16 | 17 | constexpr auto name = 18 | rfl::tuple_element_t<0, typename rfl::named_tuple_t::Fields>::name(); 19 | 20 | static_assert(name == "x"); 21 | 22 | EXPECT_TRUE(true); 23 | } 24 | 25 | } // namespace test_inheritance 26 | -------------------------------------------------------------------------------- /tests/msgpack/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-msgpack-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-msgpack-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-msgpack-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-msgpack-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-msgpack-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-msgpack-tests) 21 | 22 | -------------------------------------------------------------------------------- /tests/msgpack/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | }; 13 | 14 | TEST(msgpack, test_bytestring) { 15 | const auto test = 16 | TestStruct{.bytestring = rfl::Bytestring({std::byte{13}, std::byte{14}, 17 | std::byte{15}, std::byte{16}})}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_bytestring 22 | -------------------------------------------------------------------------------- /tests/msgpack/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(msgpack, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/msgpack/test_generic_float.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_generic_float { 10 | 11 | TEST(msgpack, test_generic_float) { 12 | rfl::Generic msgpack_data_before{}; 13 | rfl::Generic msgpack_data_after{}; 14 | 15 | msgpack_data_before = 1.4F; 16 | 17 | auto tmp_msgpack = 18 | rfl::msgpack::write(msgpack_data_before); 19 | msgpack_data_after = *rfl::msgpack::read(tmp_msgpack); 20 | 21 | EXPECT_EQ(msgpack_data_before.to_double().value(), 22 | msgpack_data_after.to_double().value()); 23 | } 24 | } // namespace test_generic_float 25 | -------------------------------------------------------------------------------- /tests/msgpack/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(msgpack, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/msgpack/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(msgpack, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/msgpack/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(msgpack, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/msgpack/test_skip.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "write_and_read.hpp" 6 | 7 | namespace test_skip { 8 | 9 | using Age = rfl::Validator, rfl::Maximum<130>>; 10 | 11 | struct Person { 12 | rfl::Skip town; 13 | rfl::Rename<"firstName", std::string> first_name; 14 | rfl::Rename<"lastName", std::string> last_name; 15 | Age age; 16 | }; 17 | 18 | TEST(msgpack, test_skip) { 19 | const auto homer = Person{.town = "Springfield", 20 | .first_name = "Homer", 21 | .last_name = "Simpson", 22 | .age = 45}; 23 | 24 | write_and_read(homer); 25 | } 26 | } // namespace test_skip 27 | -------------------------------------------------------------------------------- /tests/msgpack/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(msgpack, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/msgpack/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(msgpack, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/msgpack/test_tagged_union2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union2 { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(msgpack, test_tagged_union2) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union2 31 | -------------------------------------------------------------------------------- /tests/msgpack/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(msgpack, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/msgpack/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(msgpack, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/msgpack/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::msgpack::write(_struct); 14 | const auto res = rfl::msgpack::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::msgpack::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tests/toml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-toml-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-toml-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-toml-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_link_libraries( 12 | reflect-cpp-toml-tests 13 | PRIVATE 14 | "${REFLECT_CPP_GTEST_LIB}" 15 | ) 16 | 17 | find_package(GTest) 18 | gtest_discover_tests(reflect-cpp-toml-tests) 19 | 20 | -------------------------------------------------------------------------------- /tests/toml/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(toml, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/toml/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(toml, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/toml/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(toml, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/toml/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(toml, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/toml/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(toml, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/toml/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(toml, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/toml/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(toml, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/toml/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(toml, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/ubjson/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-ubjson-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-ubjson-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-ubjson-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_link_libraries( 12 | reflect-cpp-ubjson-tests 13 | PRIVATE 14 | "${REFLECT_CPP_GTEST_LIB}" 15 | ) 16 | 17 | find_package(GTest) 18 | gtest_discover_tests(reflect-cpp-ubjson-tests) 19 | 20 | -------------------------------------------------------------------------------- /tests/ubjson/test_bytestring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_bytestring { 9 | 10 | struct TestStruct { 11 | rfl::Bytestring bytestring; 12 | }; 13 | 14 | TEST(ubjson, test_bytestring) { 15 | const auto test = 16 | TestStruct{.bytestring = rfl::Bytestring({std::byte{13}, std::byte{14}, 17 | std::byte{15}, std::byte{16}})}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_bytestring 22 | -------------------------------------------------------------------------------- /tests/ubjson/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(ubjson, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/ubjson/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(ubjson, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/ubjson/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(ubjson, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/ubjson/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(ubjson, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/ubjson/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(ubjson, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/ubjson/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(ubjson, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/ubjson/test_tagged_union2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union2 { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(ubjson, test_tagged_union2) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union2 31 | -------------------------------------------------------------------------------- /tests/ubjson/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(ubjson, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/ubjson/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(ubjson, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/ubjson/write_and_read.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_AND_READ_ 2 | #define WRITE_AND_READ_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | void write_and_read(const auto& _struct) { 12 | using T = std::remove_cvref_t; 13 | const auto serialized1 = rfl::ubjson::write(_struct); 14 | const auto res = rfl::ubjson::read(serialized1); 15 | EXPECT_TRUE(res && true) << "Test failed on read. Error: " 16 | << res.error().what(); 17 | const auto serialized2 = rfl::ubjson::write(res.value()); 18 | EXPECT_EQ(serialized1, serialized2); 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/xml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-xml-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-xml-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-xml-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-xml-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-xml-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-xml-tests) 21 | 22 | -------------------------------------------------------------------------------- /tests/xml/test_default_if_missing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "write_and_read.hpp" 9 | 10 | namespace test_default_if_missing { 11 | 12 | struct Person { 13 | std::string name; 14 | std::vector children; 15 | }; 16 | 17 | TEST(xml, test_default_if_missing) { 18 | const auto homer = 19 | Person{.name = "Homer", 20 | .children = std::vector({"Bart", "Lisa", "Maggie"})}; 21 | 22 | write_and_read<"Person", rfl::DefaultIfMissing>(homer); 23 | } 24 | } // namespace test_default_if_missing 25 | -------------------------------------------------------------------------------- /tests/xml/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(xml, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/xml/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(xml, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/xml/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(xml, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/xml/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(xml, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/xml/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(xml, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read<"root">(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/xml/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(xml, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read<"root">(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/xml/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(xml, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read<"root">(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/xml/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(xml, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | -------------------------------------------------------------------------------- /tests/yaml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(reflect-cpp-yaml-tests) 2 | 3 | file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp") 4 | 5 | add_executable( 6 | reflect-cpp-yaml-tests 7 | ${SOURCES} 8 | ) 9 | target_precompile_headers(reflect-cpp-yaml-tests PRIVATE [["rfl.hpp"]] ) 10 | 11 | target_include_directories(reflect-cpp-yaml-tests SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") 12 | 13 | target_link_libraries( 14 | reflect-cpp-yaml-tests 15 | PRIVATE 16 | "${REFLECT_CPP_GTEST_LIB}" 17 | ) 18 | 19 | find_package(GTest) 20 | gtest_discover_tests(reflect-cpp-yaml-tests) 21 | 22 | -------------------------------------------------------------------------------- /tests/yaml/test_double.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_double { 9 | 10 | TEST(yaml, test_double) { 11 | auto obj = rfl::Generic::Object(); 12 | const double age = 10; 13 | obj["age"] = age; 14 | const auto s = rfl::yaml::write(obj); 15 | EXPECT_EQ( 16 | rfl::from_generic( 17 | rfl::yaml::read(s).value().get("age").value()) 18 | .value(), 19 | 10.0); 20 | } 21 | } // namespace test_double 22 | -------------------------------------------------------------------------------- /tests/yaml/test_enum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_enum { 10 | 11 | enum class Color { red, green, blue, yellow }; 12 | 13 | struct Circle { 14 | float radius; 15 | Color color; 16 | }; 17 | 18 | TEST(yaml, test_enum) { 19 | const auto circle = Circle{.radius = 2.0, .color = Color::green}; 20 | 21 | write_and_read(circle); 22 | } 23 | 24 | } // namespace test_enum 25 | -------------------------------------------------------------------------------- /tests/yaml/test_literal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_literal { 10 | 11 | using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie">; 12 | using LastName = rfl::Literal<"Simpson">; 13 | 14 | struct Person { 15 | rfl::Rename<"firstName", FirstName> first_name; 16 | rfl::Rename<"lastName", LastName> last_name; 17 | std::vector children; 18 | }; 19 | 20 | TEST(yaml, test_literal) { 21 | const auto bart = Person{.first_name = FirstName::make<"Bart">()}; 22 | 23 | write_and_read(bart); 24 | } 25 | } // namespace test_literal 26 | -------------------------------------------------------------------------------- /tests/yaml/test_readme_example2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_readme_example2 { 9 | 10 | struct Person { 11 | std::string first_name; 12 | std::string last_name; 13 | int age; 14 | }; 15 | 16 | TEST(yaml, test_readme_example2) { 17 | const auto homer = 18 | Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}; 19 | 20 | write_and_read(homer); 21 | } 22 | } // namespace test_readme_example2 23 | -------------------------------------------------------------------------------- /tests/yaml/test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "write_and_read.hpp" 7 | 8 | namespace test_set { 9 | 10 | struct Person { 11 | rfl::Rename<"firstName", std::string> first_name; 12 | rfl::Rename<"lastName", std::string> last_name = "Simpson"; 13 | std::unique_ptr> children; 14 | }; 15 | 16 | TEST(yaml, test_set) { 17 | auto children = std::make_unique>( 18 | std::set({"Bart", "Lisa", "Maggie"})); 19 | 20 | const auto homer = 21 | Person{.first_name = "Homer", .children = std::move(children)}; 22 | 23 | write_and_read(homer); 24 | } 25 | } // namespace test_set 26 | -------------------------------------------------------------------------------- /tests/yaml/test_string_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_string_map { 10 | TEST(yaml, test_string_map) { 11 | std::map> homer; 12 | homer.insert( 13 | std::make_pair("firstName", std::make_unique("Homer"))); 14 | homer.insert( 15 | std::make_pair("lastName", std::make_unique("Simpson"))); 16 | 17 | write_and_read(homer); 18 | } 19 | } // namespace test_string_map 20 | -------------------------------------------------------------------------------- /tests/yaml/test_tagged_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_tagged_union { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; 25 | 26 | TEST(yaml, test_tagged_union) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | write_and_read(r); 29 | } 30 | } // namespace test_tagged_union 31 | -------------------------------------------------------------------------------- /tests/yaml/test_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | namespace test_variant { 10 | 11 | struct Circle { 12 | double radius; 13 | }; 14 | 15 | struct Rectangle { 16 | double height; 17 | double width; 18 | }; 19 | 20 | struct Square { 21 | double width; 22 | }; 23 | 24 | using Shapes = std::variant>; 25 | 26 | TEST(yaml, test_variant) { 27 | const Shapes r = Rectangle{.height = 10, .width = 5}; 28 | 29 | write_and_read(r); 30 | } 31 | } // namespace test_variant 32 | -------------------------------------------------------------------------------- /tests/yaml/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "write_and_read.hpp" 8 | 9 | struct TestStruct { 10 | std::string theNormalString; 11 | std::wstring theWiderString; 12 | }; 13 | 14 | namespace test_wstring { 15 | TEST(yaml, test_wstring) { 16 | const auto test = TestStruct{.theNormalString = "The normal string", 17 | .theWiderString = L"The wider string"}; 18 | 19 | write_and_read(test); 20 | } 21 | } // namespace test_wstring 22 | --------------------------------------------------------------------------------