cppfig 0.1.0
Modern C++20 compile-time type-safe configuration library
Loading...
Searching...
No Matches
schema.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <string_view>
6#include <type_traits>
7
8#include "cppfig/setting.h"
9
10namespace cppfig {
11
12namespace detail {
13
15 template <typename T, typename... Types>
16 struct IsOneOf : std::disjunction<std::is_same<T, Types>...> { };
17
22 consteval auto IsPathPrefix(std::string_view prefix, std::string_view path) -> bool
23 {
24 return path.size() > prefix.size() && path.starts_with(prefix) && path[prefix.size()] == '.';
25 }
26
31 consteval auto IsPathWellFormed(std::string_view path) -> bool
32 {
33 if (path.empty() || path.front() == '.' || path.back() == '.') {
34 return false;
35 }
36 for (std::size_t i = 1; i < path.size(); ++i) {
37 if (path[i] == '.' && path[i - 1] == '.') {
38 return false;
39 }
40 }
41 return true;
42 }
43
45 template <typename... Settings>
46 consteval auto AllPathsWellFormed() -> bool
47 {
48 constexpr std::array<std::string_view, sizeof...(Settings)> paths = { Settings::path... };
49 for (auto path : paths) {
50 if (!IsPathWellFormed(path)) {
51 return false;
52 }
53 }
54 return true;
55 }
56
64 template <typename... Settings>
65 consteval auto AllPathsUnique() -> bool
66 {
67 constexpr std::array<std::string_view, sizeof...(Settings)> paths = { Settings::path... };
68 for (std::size_t i = 0; i < paths.size(); ++i) {
69 for (std::size_t j = i + 1; j < paths.size(); ++j) {
70 if (paths[i] == paths[j] || IsPathPrefix(paths[i], paths[j]) || IsPathPrefix(paths[j], paths[i])) {
71 return false;
72 }
73 }
74 }
75 return true;
76 }
77
78} // namespace detail
79
104template <IsSetting... Settings>
106public:
107 static constexpr std::size_t size = sizeof...(Settings);
108
109 static_assert(detail::AllPathsWellFormed<Settings...>(),
110 "Every path in ConfigSchema must be non-empty and free of empty dot-separated segments");
111
112 static_assert(detail::AllPathsUnique<Settings...>(),
113 "All paths in ConfigSchema must be unique, and none may be a prefix of another");
114
116 template <typename S>
117 static constexpr bool has_setting = detail::IsOneOf<S, Settings...>::value;
118
120 [[nodiscard]] static constexpr auto GetPaths() -> std::array<std::string_view, size>
121 {
122 return { Settings::path... };
123 }
124
126 [[nodiscard]] static constexpr auto Size() -> std::size_t { return size; }
127
132 template <typename Fn>
133 static void ForEachSetting(Fn&& fn)
134 {
135 (fn.template operator()<Settings>(), ...);
136 }
137};
138
140template <IsSetting S>
141using setting_value_type = typename S::value_type;
142
143} // namespace cppfig
Configuration schema holding all setting types.
Definition schema.h:105
static constexpr bool has_setting
Checks if a setting type is in this schema.
Definition schema.h:117
static constexpr std::size_t size
Definition schema.h:107
static constexpr auto Size() -> std::size_t
Returns the number of settings in the schema.
Definition schema.h:126
static void ForEachSetting(Fn &&fn)
Iterates over all setting types with a callable.
Definition schema.h:133
static constexpr auto GetPaths() -> std::array< std::string_view, size >
Returns all paths as a compile-time array.
Definition schema.h:120
consteval auto AllPathsWellFormed() -> bool
Helper to check that every path is well-formed at compile time.
Definition schema.h:46
consteval auto AllPathsUnique() -> bool
Helper to check if all paths are unique at compile time.
Definition schema.h:65
consteval auto IsPathPrefix(std::string_view prefix, std::string_view path) -> bool
Returns true if prefix names an ancestor of path.
Definition schema.h:22
consteval auto IsPathWellFormed(std::string_view path) -> bool
Returns true if path is a non-empty dot-separated path with no empty segments.
Definition schema.h:31
C++20 compile-time type-safe configuration library.
Definition conf.h:17
typename S::value_type setting_value_type
Helper alias to get the value type for a setting.
Definition schema.h:141
Helper to check if a type is in a parameter pack.
Definition schema.h:16