Skip to content

Commit 4614d85

Browse files
committed
init project
1 parent fcf4085 commit 4614d85

24 files changed

Lines changed: 591 additions & 152 deletions

CMakeLists.txt

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,45 @@
11
cmake_minimum_required(VERSION 3.15)
2-
project(mypkg CXX)
2+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
3+
set(CMAKE_CXX_EXTENSIONS OFF)
4+
set(CMAKE_CXX_STANDARD 26)
35

6+
project(rsl_serialize CXX)
47

8+
add_library(rsl_serialize)
9+
target_include_directories(rsl_serialize PUBLIC include)
10+
add_subdirectory(src)
511

12+
target_compile_options(rsl_serialize PUBLIC "-freflection-latest")
13+
target_include_directories(rsl_serialize PUBLIC
14+
$<INSTALL_INTERFACE:include>
15+
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
616

7-
add_library(mypkg src/mypkg.cpp)
8-
target_include_directories(mypkg PUBLIC include)
17+
find_package(rsl-util REQUIRED)
18+
target_link_libraries(rsl_serialize PUBLIC rsl::util)
919

1020

21+
install(TARGETS rsl_serialize)
22+
install(DIRECTORY include/ DESTINATION include)
1123

12-
set_target_properties(mypkg PROPERTIES PUBLIC_HEADER "include/mypkg.h")
13-
install(TARGETS mypkg)
24+
option(BUILD_EXAMPLES "Enable examples" ON)
25+
if (BUILD_EXAMPLES)
26+
add_subdirectory(example)
27+
endif()
28+
29+
option(BUILD_TESTING "Enable tests" ON)
30+
option(BUILD_EXAMPLES "Enable examples" ON)
31+
32+
if (BUILD_TESTING)
33+
message(STATUS "Building unit tests")
34+
35+
enable_testing()
36+
add_executable(rsl_serialize_test)
37+
add_subdirectory(test)
38+
39+
find_package(GTest REQUIRED)
40+
target_link_libraries(rsl_serialize_test PRIVATE rsl_serialize)
41+
target_link_libraries(rsl_serialize_test PRIVATE GTest::gtest)
42+
43+
include(GoogleTest)
44+
gtest_discover_tests(rsl_serialize_test)
45+
endif()

conanfile.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from conan import ConanFile
22
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
3+
import os
34

4-
5-
class pkgRecipe(ConanFile):
6-
name = "mypkg"
5+
class rslSerializeRecipe(ConanFile):
6+
name = "rsl-serialize"
77
version = "0.1"
88
package_type = "library"
99

@@ -16,11 +16,17 @@ class pkgRecipe(ConanFile):
1616

1717
# Binary configuration
1818
settings = "os", "compiler", "build_type", "arch"
19-
options = {"shared": [True, False], "fPIC": [True, False]}
20-
default_options = {"shared": False, "fPIC": True}
19+
options = {
20+
"shared": [True, False],
21+
"fPIC": [True, False],
22+
"examples": [True, False],
23+
"editable": [True, False],
24+
"tests" : [True, False]
25+
}
26+
default_options = {"shared": False, "fPIC": True, "examples": False, "editable": False, "tests": False}
2127

2228
# Sources are located in the same place as this recipe, copy them to the recipe
23-
exports_sources = "CMakeLists.txt", "src/*", "include/*"
29+
exports_sources = "CMakeLists.txt", "src/*", "include/*", "test/*"
2430

2531
def config_options(self):
2632
if self.settings.os == "Windows":
@@ -30,9 +36,13 @@ def configure(self):
3036
if self.options.shared:
3137
self.options.rm_safe("fPIC")
3238

39+
def requirements(self):
40+
self.requires("rsl-util/0.1", transitive_headers=True)
41+
self.test_requires("gtest/1.14.0")
42+
3343
def layout(self):
3444
cmake_layout(self)
35-
45+
3646
def generate(self):
3747
deps = CMakeDeps(self)
3848
deps.generate()
@@ -41,13 +51,24 @@ def generate(self):
4151

4252
def build(self):
4353
cmake = CMake(self)
44-
cmake.configure()
54+
cmake.configure(
55+
variables={
56+
"BUILD_TESTING": self.options.tests,
57+
"BUILD_EXAMPLES": self.options.examples,
58+
})
4559
cmake.build()
60+
if self.options.editable:
61+
# package is in editable mode - make sure it's installed after building
62+
cmake.install()
4663

4764
def package(self):
4865
cmake = CMake(self)
4966
cmake.install()
5067

5168
def package_info(self):
52-
self.cpp_info.libs = ["mypkg"]
53-
69+
self.cpp_info.set_property("cmake_file_name", "rsl-serialize")
70+
self.cpp_info.components["config"].set_property("cmake_target_name", "rsl::serialize")
71+
self.cpp_info.components["config"].includedirs = ["include"]
72+
self.cpp_info.components["config"].libdirs = ["lib"]
73+
self.cpp_info.components["config"].libs = ["rsl_serialize"]
74+
# self.cpp_info.components["config"].requires = ["rsl-util::util"]

example/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
project(rsl_serialize)
2+
3+
function(DEFINE_EXAMPLE TARGET)
4+
add_executable(example_${TARGET} "${TARGET}.cpp")
5+
target_link_libraries(example_${TARGET} PRIVATE rsl_serialize)
6+
endfunction()
7+
8+
DEFINE_EXAMPLE(xml)

example/xml.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <rsl/xml>
2+
#include <print>
3+
#include "rsl/serializer/xml/annotations.hpp"
4+
#include <vector>
5+
6+
7+
struct Foo{};
8+
9+
struct EmptyClass{
10+
struct { struct {
11+
std::vector<Foo> elts{{}, {}, {}};
12+
13+
} bar; } foo;
14+
struct KK {} zoinks;
15+
std::vector<Foo> elts;
16+
[[=rsl::xml::attribute]] bool passed = true;
17+
[[=rsl::xml::attribute]] std::optional<int> bar;
18+
};
19+
20+
int main() {
21+
auto result = rsl::to_xml(EmptyClass{.elts={{}, {}}});
22+
std::println("{}", result);
23+
}

include/mypkg.h

Lines changed: 0 additions & 13 deletions
This file was deleted.

include/rsl/json5

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
#include <rsl/serialize>
3+
4+
namespace rsl {
5+
6+
}

include/rsl/repr

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include <rsl/serialize>
3+
#include <string>
4+
5+
#include <meta>
6+
7+
namespace rsl {
8+
template <auto V>
9+
struct Constant{};
10+
11+
struct repr_tag{};
12+
13+
template <typename T>
14+
constexpr std::string repr(T&& value, repr_tag={}){
15+
return std::to_string(value);
16+
}
17+
18+
template <auto V>
19+
constexpr std::string repr(Constant<V>, repr_tag={}){
20+
return std::to_string(V);
21+
}
22+
23+
template <typename T>
24+
std::ostream& operator<<(std::ostream& stream, std::string(*)(T&&, repr_tag)){
25+
return stream << std::string_view(define_static_string(display_string_of(remove_cvref(^^T))));
26+
}
27+
28+
template <auto V>
29+
std::ostream& operator<<(std::ostream& stream, std::string(*fnc)(Constant<V>, repr_tag)){
30+
return stream << fnc(Constant<V>{}, {});
31+
}
32+
}
33+
34+
#ifdef RSL_GLOBAL_REPR
35+
using rsl::repr;
36+
#endif

include/rsl/serialize

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
#include <ranges>
3+
#include "serializer/machinery.hpp"
4+
#include "serializer/util.hpp"
5+
6+
namespace rsl {
7+
template <typename T, typename V>
8+
void serialize(T&& serializer, V&& data) {
9+
serializer::Meta<std::remove_cvref_t<V>>{}.visit(std::forward<T>(serializer),
10+
std::forward<V>(data));
11+
}
12+
13+
template <serializer::complete_type V, typename T, std::ranges::forward_range R>
14+
V deserialize(T&& deserializer, R&& data) {}
15+
16+
template <typename T, serializer::complete_type V>
17+
void serialize_type(T&& serializer) {
18+
return serializer.template operator()<^^V>();
19+
}
20+
21+
template <typename T, std::ranges::forward_range R>
22+
consteval std::meta::info deserialize_type(T&& deserializer, R&& data) {
23+
return deserializer(data);
24+
}
25+
26+
} // namespace rsl

include/rsl/serializer/customization.hpp

Whitespace-only changes.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#pragma once
2+
#include <meta>
3+
#include <ranges>
4+
#include "util.hpp"
5+
6+
namespace rsl::serializer {
7+
8+
template <typename T>
9+
concept is_meta = requires {
10+
{ T::info } -> std::convertible_to<std::meta::info>;
11+
};
12+
13+
template <typename T>
14+
concept has_members = is_meta<T> && requires {
15+
{ T::members } -> std::convertible_to<std::span<std::meta::info const>>;
16+
};
17+
18+
template <typename T>
19+
concept is_iterable = is_meta<T> && T::iterable;
20+
21+
template <typename T>
22+
concept is_optional = is_meta<T> && T::is_optional;
23+
24+
template <typename T>
25+
struct Meta;
26+
27+
template <typename T>
28+
requires(std::is_scalar_v<T>)
29+
struct Meta<T> {
30+
static constexpr std::meta::info info = ^^T;
31+
32+
template <typename S, typename F, typename U>
33+
requires(std::same_as<std::remove_cvref_t<U>, T>)
34+
void visit(this S&& self, F&& visitor, U&& value) {
35+
std::invoke(std::forward<F>(visitor), std::forward<S>(self), std::forward<U>(value));
36+
}
37+
38+
template <typename U, typename F>
39+
requires(std::same_as<std::remove_cvref_t<U>, T>)
40+
void descend(F&& visitor, U&& value) {}
41+
};
42+
43+
template <std::size_t Idx, std::meta::info R, typename T>
44+
struct Member : Meta<T> {
45+
static constexpr std::meta::info info = R;
46+
static constexpr std::size_t index = Idx;
47+
};
48+
49+
template <typename T>
50+
requires(std::is_aggregate_v<T> && !std::is_array_v<T>)
51+
struct Meta<T> {
52+
static constexpr std::meta::info info = ^^T;
53+
static constexpr auto members =
54+
define_static_array(nonstatic_data_members_of(info, std::meta::access_context::current()));
55+
56+
template <typename S, typename F, typename U>
57+
requires(std::same_as<std::remove_cvref_t<U>, T>)
58+
void visit(this S&& self, F&& visitor, U&& value) {
59+
std::invoke(std::forward<F>(visitor), std::forward<S>(self), std::forward<U>(value));
60+
}
61+
62+
template <typename F, typename U>
63+
requires(std::same_as<std::remove_cvref_t<U>, T>)
64+
void descend(F&& visitor, U&& value) {
65+
template for (constexpr auto Idx : std::views::iota(0ZU, members.size())) {
66+
constexpr auto M = members[Idx];
67+
Member<Idx, M, typename[:type_of(M):]>{}.visit(visitor, value.[:M:]);
68+
}
69+
}
70+
};
71+
72+
template <std::ranges::range T>
73+
requires std::constructible_from<std::initializer_list<typename T::value_type>>
74+
struct Meta<T> {
75+
using type = T;
76+
using element_type = typename T::value_type;
77+
constexpr static std::meta::info info = ^^T;
78+
constexpr static bool can_descend = true;
79+
constexpr static bool iterable = true;
80+
constexpr static bool associative = requires {
81+
typename type::key_type;
82+
typename type::mapped_type;
83+
};
84+
85+
template <typename S, typename F, typename U>
86+
requires(std::same_as<std::remove_cvref_t<U>, T>)
87+
void visit(this S&& self, F&& visitor, U&& value) {
88+
std::invoke(std::forward<F>(visitor), std::forward<S>(self), std::forward<U>(value));
89+
}
90+
91+
template <typename F, typename U>
92+
requires(std::same_as<std::remove_cvref_t<U>, T>)
93+
void descend(F&& visitor, U&& value) {
94+
for (auto&& item : value) {
95+
Meta<std::remove_cvref_t<decltype(item)>>{}.visit(visitor, item);
96+
}
97+
}
98+
};
99+
100+
template <typename T>
101+
struct Meta<std::optional<T>> {
102+
using type = std::optional<T>;
103+
using element_type = T;
104+
constexpr static std::meta::info info = dealias(^^type);
105+
constexpr static bool is_optional = true;
106+
107+
template <typename S, typename F, typename U>
108+
requires(std::same_as<std::remove_cvref_t<U>, type>)
109+
void visit(this S&& self, F&& visitor, U&& value) {
110+
std::invoke(std::forward<F>(visitor), std::forward<S>(self), std::forward<U>(value));
111+
}
112+
};
113+
114+
} // namespace rsl::serializer

0 commit comments

Comments
 (0)