44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |  |
52 |
53 |
54 |
55 | $projectname $projectnumber
56 |
57 | $projectbrief
58 | |
59 |
60 |
61 |
62 |
63 | $projectbrief
64 | |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | $searchbox |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/doc/changelog.md:
--------------------------------------------------------------------------------
1 | Change Log {#changelog}
2 | ==========
3 |
4 | # Version 2.0 - Past Prologue
5 |
6 | ## Bug Fixes
7 | * Moved from `pragma once` to `#ifndef` to allow for multiple raberu files to coexist in multiple projects.
8 | * Fixed a regression in Visual Studio that affected ability to run tests.
9 | * Fix #6 - Compile-time ID are now properly displayed and compared without any issues due to terminal `\0`.
10 |
11 | ## New Features
12 | * Fix #4 - Simplify and generalize custom keyword generation
13 | A new CRTP class `rbr::as_keyword` streamlines the definition of compact keyword by users while
14 | supporting the whole range of built-in keywords. Associated documentation has been updated.
15 |
16 | * Fix #2 - Implement direct keyword value access
17 | Keyword can now fetch themselves from a bundles of options. E.g
18 |
19 | ``` c++
20 | inline constexpr auto coord_ = "coord"_kw;
21 | inline constexpr auto is_modal_ = "is_modal"_fl;
22 |
23 | auto x = coord_(coord_ = "Jane"s, is_modal_);
24 | ```
25 |
26 | * Fix #5 - Mass extractors for keyword and values
27 | `rbr::keywords` and`rbr::values` can be used to retrieve a tuple-like object containing all the
28 | keywords or values from a bundle of options.
29 |
30 | * `rbr::get_type` is removed and is replaced by `rbr::fetch` and `rbr::result::fetch_t`.
31 | This functions provides an infix syntax for options access.
32 |
33 | # Version 1.0 - Emissary
34 |
35 | ## First autonomous public release.
36 |
37 | **RABERU** (ラベル組) is now independent of the OFW repository.
38 |
--------------------------------------------------------------------------------
/doc/color.css:
--------------------------------------------------------------------------------
1 | html
2 | {
3 | /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */
4 | --primary-dark-color: hsl(0, 100%, 10%);
5 | --primary-color: hsl(0, 100%, 25%);
6 | --primary-light-color: hsl(0, 100%, 40%);
7 |
8 | /* page base colors */
9 | --page-background-color: white;
10 | --page-foreground-color: hsl(0, 100%, 10%);
11 | --page-secondary-foreground-color: hsl(0, 100%, 25%);
12 | }
13 |
--------------------------------------------------------------------------------
/doc/custom.hpp:
--------------------------------------------------------------------------------
1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY
2 |
3 | //==================================================================================================
4 | /**
5 | \page custom Tutorial: Customizing Keyword
6 |
7 | @tableofcontents
8 |
9 | \section custom_01 Using Pre-bound keyword
10 |
11 | Sometimes you wish you could have a terser syntax for keyword parameters.
12 | Let's say you want to pass a compile-time unrolling factor to some algorithm.
13 |
14 | @code
15 | // This is working but a bit verbose
16 | using namespace rbr::literals;
17 | inline constexpr auto unroll = rbr::keyword("unrolling"_id);
18 |
19 | auto x = my_algorithm( unroll = std::integral_constant
{});
20 | @endcode
21 |
22 | One idea is to defines a **pre-bound keyword parameter**, i.e constructs an inline
23 | variable initialized with the result of the assignment of a value to a keyword.
24 |
25 | @code
26 | using namespace rbr::literals;
27 | inline constexpr auto unrolling = rbr::keyword("unrolling"_id);
28 |
29 | template inline constexpr auto unroll = (unrolling = std::integral_constant{});
30 | @endcode
31 |
32 | `unroll` is now ready to be passed around. To retrieve it, you'll need to use
33 | the `unrolling` keyword.
34 |
35 | @include doc/tutorial04.cpp
36 |
37 | \section custom_02 Custom RABERU Keywords
38 |
39 | The keywords provided by **RABERU** can also be extended to propose a better user experience.
40 | This includes using user-defined type instead of **RABERU** long symbol to improve diagnostic
41 | , complex checks or provide custom display when using stream insertion of settings.
42 |
43 | \subsection custom-extension Extending RABERU Keywords
44 | Let's start again with our unrolling option. This time we want to be able to be sure nobody
45 | will use it with a non integral constant value and to display the value in a more informative way.
46 | To do so, we can inherits from `rbr::as_keyword`, a CRTP enabled base class:
47 |
48 | @code
49 | struct unrolling : rbr::as_keyword
50 | {
51 | template
52 | constexpr auto operator=(std::integral_constant const&) const noexcept
53 | {
54 | return rbr::option>{};
55 | }
56 |
57 | std::ostream& display(std::ostream& os, auto v) const { return os << "Unroll Factor: " << v; }
58 | };
59 |
60 | template inline constexpr auto unroll = (unrolling{} = std::integral_constant{});
61 | @endcode
62 |
63 | What if we call `f( unrolling{} = 3.f );` ? Well, we go this error message:
64 |
65 | @code
66 | example.cpp:25:18: error: no viable overloaded '='
67 | f( unrolling{} = 3.f );
68 | ~~~~~~~~~~~ ^ ~~~
69 | :8:18: note: candidate template ignored: could not match 'integral_constant' against 'float'
70 | constexpr auto operator=(std::integral_constant const&) const noexcept
71 | @endcode
72 |
73 | \subsection custom-display Custom Keywords Display
74 | Let's now improve the output of the option. Currently, the output is like:
75 |
76 | @code
77 | [unrolling] : 8 (std::integral_constant)
78 | @endcode
79 |
80 | A bit verbose especially for end-user.
81 | Keyword-like entity can specialize a `display` member function to replace this output by a custom one.
82 |
83 | @code
84 | struct unrolling : rbr::as_keyword
85 | {
86 | template
87 | constexpr auto operator=(std::integral_constant const&) const noexcept
88 | {
89 | return rbr::option>{};
90 | }
91 |
92 | std::ostream& display(std::ostream& os, auto v) const { return os << "Unroll Factor: " << v; }
93 | };
94 | @endcode
95 |
96 | The `display` member takes the output stream and the actual value of the option to be displayed.
97 | One can then arrange those as they see fit, leading to a better output:
98 |
99 | @include doc/tutorial05.cpp
100 |
101 | **/
102 | //==================================================================================================
103 |
--------------------------------------------------------------------------------
/doc/index.hpp:
--------------------------------------------------------------------------------
1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY
2 |
3 | //==================================================================================================
4 | //! \mainpage The Fancy Named Parameters Library
5 | //!
6 | //! **RABERU** provides a way to define and use named parameters, *i.e* a list of values assigned to
7 | //! arbitrary keyword-like identifiers, to functions.
8 | //!
9 | //! It does so by providing:
10 | //!
11 | //! * a protocol to define such keywords.
12 | //! * a type to process such aggregate of parameters.
13 | //! * a `constexpr`-compatible implementation for all of those.
14 | //!
15 | //! # A Short Example
16 | //!
17 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
18 | //! #include
19 | //! #include
20 | //! #include
21 | //!
22 | //! using namespace rbr::literals;
23 | //!
24 | //! template
25 | //! auto replicate( P0 p0, P1 p1 )
26 | //! {
27 | //! auto const params = rbr::settings(p0,p1);
28 | //! return std::string( params["replication"_kw], params["letter"_kw] );
29 | //! }
30 | //!
31 | //! int main()
32 | //! {
33 | //! std::cout << replicate("replication"_kw = 9, "letter"_kw = 'z' ) << "\n";
34 | //! std::cout << replicate("letter"_kw = '!' , "replication"_kw = 3) << "\n";
35 | //! }
36 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | //!
38 | //! # Licence
39 | //!
40 | //! This library is licensed under the [Boost Software License](https://opensource.org/licenses/BSL-1.0):
41 | //!
42 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none
43 | //! Copyright : RABERU Project Contributors
44 | //!
45 | //! Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the
46 | //! software and accompanying documentation covered by this license (the "Software") to use, reproduce,
47 | //! display, distribute, execute, and transmit the Software, and to prepare derivative works of the
48 | //! Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the
49 | //! following:
50 | //!
51 | //! The copyright notices in the Software and this entire statement, including the above license grant,
52 | //! this restriction and the following disclaimer, must be included in all copies of the Software, in
53 | //! whole or in part, and all derivative works of the Software, unless such copies or derivative works
54 | //! are solely in the form of machine-executable object code generated by a source language processor.
55 | //!
56 | //! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
57 | //! NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
58 | //! NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE
59 | //! BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
60 | //! FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 | //!
63 | //==================================================================================================
64 |
--------------------------------------------------------------------------------
/doc/layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
--------------------------------------------------------------------------------
/doc/licence.md:
--------------------------------------------------------------------------------
1 | Licence {#licence}
2 | =======
3 |
4 | This library is licensed under the [Boost Software License](https://opensource.org/licenses/BSL-1.0):
5 |
6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none
7 | Copyright : RABERU Project Contributors
8 |
9 | Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the
10 | software and accompanying documentation covered by this license (the "Software") to use, reproduce,
11 | display, distribute, execute, and transmit the Software, and to prepare derivative works of the
12 | Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the
13 | following:
14 |
15 | The copyright notices in the Software and this entire statement, including the above license grant,
16 | this restriction and the following disclaimer, must be included in all copies of the Software, in
17 | whole or in part, and all derivative works of the Software, unless such copies or derivative works
18 | are solely in the form of machine-executable object code generated by a source language processor.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
22 | NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE
23 | BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 |
--------------------------------------------------------------------------------
/doc/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfalcou/raberu/3c94ac628a80ac9d21e71b4e3c5719e80a82a684/doc/logo.png
--------------------------------------------------------------------------------
/doc/setup.hpp:
--------------------------------------------------------------------------------
1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY
2 |
3 | //==================================================================================================
4 | /**
5 | @page setup Setup
6 |
7 | @tableofcontents
8 |
9 | @section setup-source Install from the source
10 |
11 | Code source of **RABERU** is available on GitHub and can be retrieved via the following command:
12 |
13 | @code
14 | $ git clone https://github.com/jfalcou/raberu.git
15 | @endcode
16 |
17 | Once retrieved, you should have a `raberu` folder which contains the whole source code.
18 |
19 | Create a `build` directory here and enter it. Once in the `build` directory,
20 | you can use **CMake** to generate the build system for **RABERU**. We recommend using
21 | Ninja but any build system is fine.
22 |
23 | @code
24 | $ mkdir build
25 | $ cd build
26 | $ cmake .. -G Ninja
27 | @endcode
28 |
29 | Once **CMake** completes, you can use the `install` target to build and install **RABERU**.
30 | By default, the library will be installed in the `/usr/local` directory, thus requiring
31 | root privileges.
32 |
33 | @code
34 | $ sudo ninja install
35 | @endcode
36 |
37 | You can select an alternative installation path by specifying the `CMAKE_INSTALL_PREFIX`
38 | option at configuration time.
39 |
40 | @code
41 | $ cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=path/to/install
42 | $ ninja install
43 | @endcode
44 |
45 | Once installed, **RABERU** is usable directly by providing the path to its installed files.
46 |
47 | @section setup-standalone Standalone setup
48 |
49 | You can also use **RABERU** via a single standalone file that can be vendored in your own project without
50 | having to deal with **RABERU** as a dependency.
51 |
52 | Simply use `wget` to fetch the latest version and place it where you want:
53 |
54 | @code
55 | wget https://raw.githubusercontent.com/jfalcou/raberu/main/standalone/raberu/raberu.hpp
56 | @endcode
57 |
58 | Use **RABERU** by just compiling your code with the include path pointing to the location of this single file.
59 |
60 | @section setup-fetchcontent CMake FetchContent
61 |
62 | You can also use CMake FetchContent operation and use the `raberu::raberu` library target that our CMake exports.
63 |
64 | @code{cmake}
65 | ##==================================================================================================
66 | ## Your project setup
67 | ##==================================================================================================
68 | cmake_minimum_required(VERSION 3.22)
69 | project(raberu-fetch LANGUAGES CXX)
70 |
71 | include(FetchContent)
72 | FetchContent_Declare(raberu GIT_REPOSITORY "https://github.com/jfalcou/raberu.git")
73 | FetchContent_MakeAvailable(raberu)
74 |
75 | add_executable(test_raberu ../main.cpp)
76 | target_link_libraries(test_raberu PUBLIC raberu::raberu)
77 | @endcode
78 |
79 | @section setup-cpm Setup with CPM
80 |
81 | The **RABERU** library can be setup using [CPM](https://github.com/cpm-cmake/CPM.cmake):
82 |
83 | @code{cmake}
84 | ##==================================================================================================
85 | ## Your project setup
86 | ##==================================================================================================
87 | cmake_minimum_required(VERSION 3.18)
88 | project(raberu-cpm LANGUAGES CXX)
89 |
90 | # Setup CPM - See https://github.com/cpm-cmake/CPM.cmake#adding-cpm
91 | include(cpm.cmake)
92 |
93 | CPMAddPackage ( NAME raberu
94 | GIT_REPOSITORY "https://github.com/jfalcou/raberu.git"
95 | OPTIONS "RABERU_BUILD_TEST OFF"
96 | )
97 |
98 | add_executable(test_raberu ../main.cpp)
99 | target_link_libraries(test_raberu PUBLIC raberu::raberu)
100 | @endcode
101 | **/
102 | //==================================================================================================
103 |
--------------------------------------------------------------------------------
/doc/tutorial.hpp:
--------------------------------------------------------------------------------
1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY
2 |
3 | //==================================================================================================
4 | /**
5 | \page tutorial RABERU 101
6 |
7 | @tableofcontents
8 |
9 | The **RABERU** library provides a way to define and use named parameters, *i.e* a list of values assigned to
10 | arbitrary keyword-like identifiers, to functions.
11 |
12 | It does so by providing:
13 |
14 | + a protocol to define such keywords.
15 | + a type to process such aggregate of parameters.
16 | + a `constexpr`-compatible implementation for all of those.
17 |
18 |
19 | \section tutorial_01 Keyword, Options, Settings
20 |
21 | Let's define a small function - `replicate` - that takes a character `c` and an integer `n` as parameters and
22 | return a string containing `c` repeated `n` times. As we want our users to have maximum flexibility, we will
23 | pass those parameters as keyword/value pairs.
24 |
25 | @include doc/tutorial01.cpp
26 |
27 | Let's decompose this code:
28 |
29 | + First, we define the `replicate` function. It takes two parameters which model
30 | rbr::concepts::option, ensuring the parameters are valid **RABERU** key/value pairs.
31 | + Those parameters are then turned into an instance of rbr::settings which will provide the interface to query values from the bundle of parameters.
32 | + We retrieve the value associated to the `"replication"_kw` and `"letter"_kw` keywords.
33 | + In the `main` function, we call `replicate` by passing key/value pairs. Note that the keys are the exact same identifiers than those used inside the function. Their order is irrelevant.
34 |
35 | That's it. The `replicate` function can now takes keywords arguments and as long as the proper keywords are used, it will work as intended.
36 |
37 | \section tutorial_02 Flavor of Keywords
38 |
39 | \subsection tutorial-keywords Regular keywords
40 |
41 | Let's say you want to pass a compile-time unrolling factor to some algorithm.
42 | You can use a regular keyword as seen in the tutorial:
43 |
44 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
45 | auto x = my_algorithm( "unroll"_kw = std::integral_constant{});
46 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 |
48 | This is working but a bit verbose. Another issue can be that documenting the fact
49 | that your functions awaits a `"unroll"_kw` maybe cumbersome.
50 |
51 | A nicer way to simplify the user experience is to preemptively defines a keyword variable.
52 |
53 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
54 | inline constexpr auto unroll = "unroll"_kw;
55 |
56 | auto x = my_algorithm( unroll = std::integral_constant{});
57 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58 |
59 | Slightly terser and far easier to document.
60 | You can also use the rbr::keyword factory that takes an ID and returns a keyword instance
61 |
62 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
63 | inline constexpr auto unroll = rbr::keyword("unroll"_id);
64 |
65 | auto x = my_algorithm( unroll = std::integral_constant{});
66 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67 |
68 | \subsection tutorial-flags Flags
69 | Sometimes, you just want to check if a given parameter has been passed but you don't really care about an associated value. Such keyword parameters are **flags**, carrying information about their sole presence without the need ot be bound to a value.
70 |
71 | They work in a similar way than regular keyword parameters but use the `_fl` user-defined literal
72 | ior the rbr::flag factory. Their value can be retrieved via rbr::settings::operator[]. If present, the value returned is `std::true_type`, otherwise `std::false_type` is returned.
73 |
74 | @include doc/tutorial02.cpp
75 |
76 | \subsection tutorial-checked Checked keywords
77 | Regular keywords accept value of any types. Flag keyword implicitly behaves as boolean parameters.
78 | What if you need to have a keyword accepting values of a specific type ? Or, in more complex
79 | context, what if you need a keyword accepting values which types satisfy an arbitrary set of
80 | constraints ?
81 |
82 | To do so, we'll need to use the rbr::keyword factory function that
83 | accepts an optional template parameter. If this template parameter is a type,
84 | the keyword is setup to only accept value of this exact type.
85 |
86 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
87 | using namespace rbr::literals;
88 |
89 | // color can only accept unsigned 32 bits integer
90 | auto color = rbr::keyword("color"_id);
91 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92 |
93 | If this template parameter is a unary template meta-function `F`, the keyword is setup to only
94 | accept value which type satisfy `F::value == true`.
95 |
96 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
97 | using namespace rbr::literals;
98 |
99 | template struct large_type
100 | {
101 | static constexpr auto value = sizeof(T) >= 4;
102 | };
103 |
104 | // entropy can only accept types of at least 32 bits
105 | inline constexpr auto entropy = rbr::keyword( "entropy"_id);
106 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107 |
108 | \section tutorial_03 Settings
109 |
110 | Another important **RABERU** component is rbr::settings. It aggregates key/value pairs in a way their
111 | exploitation is simplified. rbr::settings provides functions for retrieving value from keywords,
112 | inspect the stored keywords and more.
113 |
114 | \subsection tutorial-settings Defining a Settings
115 | rbr::settings can be directly constructed from an arbitrary list of options, ie values bound to
116 | a keyword. Once constructed, its operator[] can be used to fetch the value of a given keyword.
117 |
118 | @include doc/tutorial03.cpp
119 |
120 | \subsection tutorial-stream Stream insertion
121 | rbr::settings can be streamed to display the list of keyword/value pairs it contains
122 |
123 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++
124 | #include
125 | #include
126 |
127 | int main()
128 | {
129 | using namespace rbr::literals;
130 |
131 | auto values = rbr::settings("size"_kw = 75ULL, "transparent"_fl, "value"_kw = 7.7f);
132 |
133 | std::cout << values << "\n";
134 | }
135 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136 |
137 | The expected output should be:
138 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139 | 'size' : 75 (long long unsigned int)
140 | 'transparent' : 1 (std::integral_constant)
141 | 'value' : 7.7 (float)
142 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
143 | **/
144 | //==================================================================================================
145 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo/drop.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | namespace rbr
11 | {
12 | namespace _
13 | {
14 | template
15 | struct filter
16 | {
17 | using type = _::keys;
18 |
19 | template constexpr auto operator+(keys const&) const
20 | {
21 | using kw_t = typename T::keyword_type;
22 | if constexpr(!stdfix::same_as) return filter{};
23 | else return *this;
24 | }
25 | };
26 |
27 | template< typename K, typename S> struct select_keys;
28 |
29 | template< typename K, concepts::option... Os>
30 | struct select_keys>
31 | : decltype((filter{} + ... + _::keys{}))
32 | {
33 | };
34 | }
35 |
36 | //====================================================================================================================
37 | //! @ingroup stng
38 | //! @related rbr::settings
39 | //! @brief Remove an option from a rbr::settings
40 | //!
41 | //! Build a rbr::settings containing all options from s except for any option bound to the `k`
42 | //! rbr::keyword.
43 | //!
44 | //! @param k Keyword to remove
45 | //! @param s Original rbr::settings
46 | //! @return An instance of rbr::settings containing all options of `s` except those bound to `k`.
47 | //!
48 | //! ## Example:
49 | //! @include doc/drop.cpp
50 | //====================================================================================================================
51 | template
52 | [[nodiscard]] constexpr auto drop([[maybe_unused]] K const& k, settings const& s)
53 | {
54 | using selected_keys_t = typename _::select_keys>::type;
55 |
56 | return [&]( _::keys )
57 | {
58 | // Rebuild a new settings by going over the keys that we keep
59 | return rbr::settings{ (Ks{} = s[Ks{}] )...};
60 | }(selected_keys_t{});
61 | }
62 |
63 | namespace result
64 | {
65 | template
66 | struct drop
67 | {
68 | using type = decltype( rbr::drop(std::declval(),std::declval()...) );
69 | };
70 |
71 | template
72 | using drop_t = typename drop::type;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo/fetch.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | namespace rbr
11 | {
12 | //====================================================================================================================
13 | //! @ingroup stng
14 | //! @brief Retrieved a value via a keyword
15 | //!
16 | //! Retrieve the value bound to a given keyword `k` inside a variadic list of rbr::options.
17 | //! If such a keyword is not present, either an instance of rbr::unknown_key is returned or
18 | //! a default value or function call will be returned.
19 | //!
20 | //! @param k Keywords to check
21 | //! @param os Options to inspect
22 | //! @return If any, the value bound to `k`.
23 | //!
24 | //! ## Helper Types
25 | //! @code
26 | //! namespace rbr::result
27 | //! {
28 | //! template struct fetch
29 | //!
30 | //! template
31 | //! using fetch_t = typename fetch::type;
32 | //! }
33 | //! @endcode
34 | //!
35 | //! Return the type of a call to rbr::fetch.
36 | //!
37 | //! ## Example:
38 | //! @include doc/fetch.cpp
39 | //====================================================================================================================
40 | template
41 | constexpr decltype(auto) fetch(K const& k, Os const&... os)
42 | {
43 | auto const opts = settings(os...);
44 | return opts[k];
45 | }
46 |
47 | //! @overload
48 | template
49 | constexpr decltype(auto) fetch(_::type_or_ const& k, Os const&... os)
50 | {
51 | auto const opts = settings(os...);
52 | return opts[k];
53 | }
54 |
55 | //! @overload
56 | template
57 | constexpr decltype(auto) fetch(K const& k, Settings const& opts)
58 | {
59 | return opts[k];
60 | }
61 |
62 | namespace result
63 | {
64 | template struct fetch;
65 |
66 | template
67 | struct fetch
68 | {
69 | using type = decltype( rbr::fetch(Keyword, std::declval()...) );
70 | };
71 |
72 | template
73 | struct fetch
74 | {
75 | using type = decltype( rbr::fetch(Keyword, std::declval()) );
76 | };
77 |
78 | template
79 | using fetch_t = typename fetch::type;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo/is_equivalent.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | #include
11 |
12 | namespace rbr
13 | {
14 | //====================================================================================================================
15 | //! @ingroup stng
16 | //! @brief Checks the equivalence of two rbr::settings
17 | //!
18 | //! Two rbr::settings are equivalent if they contain the same exact set of keywords irregardless
19 | //! of their values or value types.
20 | //!
21 | //! @tparam S1 rbr::settings to compare
22 | //! @tparam S2 rbr::settings to compare
23 | //!
24 | //! ## Helper Value
25 | //! @code
26 | //! namespace rbr
27 | //! {
28 | //! template
29 | //! inline constexpr bool is_equivalent_v = is_equivalent::value;
30 | //! }
31 | //! @endcode
32 | //!
33 | //! Contains the result of a call to rbr::is_equivalent.
34 | //!
35 | //! ## Example:
36 | //! @include doc/is_equivalent.cpp
37 | //====================================================================================================================
38 | template
39 | struct is_equivalent
40 | : std::bool_constant< _::is_equivalent< result::keywords_t
41 | , result::keywords_t
42 | >::value
43 | && _::is_equivalent< result::keywords_t
44 | , result::keywords_t
45 | >::value
46 | >
47 | {};
48 |
49 | template
50 | inline constexpr bool is_equivalent_v = is_equivalent::value;
51 | }
52 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo/keys_values.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | namespace rbr
11 | {
12 | namespace result
13 | {
14 | template class List = types> struct keywords;
15 | template class List = types> struct values;
16 |
17 | template class List>
18 | struct keywords, List>
19 | {
20 | using type = List;
21 | };
22 |
23 | template class List>
24 | struct values, List>
25 | {
26 | using type = List;
27 | };
28 |
29 | template class List = types>
30 | using keywords_t = typename keywords::type;
31 |
32 | template class List = types>
33 | using values_t = typename values::type;
34 | }
35 |
36 | //====================================================================================================================
37 | //! @ingroup stng
38 | //! @brief Retrieved the list of all keywords in a settings
39 | //!
40 | //! @tparam List A n-ary template type to hold the result values
41 | //! @param s Settings to inspect
42 | //! @return An instance of rbr::type containing all the keyword from a rbr::settings.
43 | //!
44 | //! ## Helper Types
45 | //! @code
46 | //! namespace rbr::result
47 | //! {
48 | //! template class List, typename Settings> struct keywords;
49 | //!
50 | //! template class List, typename Settings>
51 | //! using keywords_t = typename keywords::type;
52 | //! }
53 | //! @endcode
54 | //!
55 | //! Return the type of a call to rbr::keywords.
56 | //!
57 | //! ## Example:
58 | //! @include doc/keywords.cpp
59 | //====================================================================================================================
60 | template class List, typename... Opts>
61 | constexpr auto keywords([[maybe_unused]]rbr::settings const& s)
62 | {
63 | return result::keywords_t,List>{typename Opts::keyword_type{}...};
64 | }
65 |
66 | //====================================================================================================================
67 | //! @ingroup stng
68 | //! @brief Retrieved the list of all value stored in a settings
69 | //!
70 | //! @tparam List A n-ary template type to hold the result
71 | //! @param s Settings to inspect
72 | //! @return an instance of rbr::type containing all the values from a rbr::settings.
73 | //!
74 | //! ## Helper Types
75 | //! @code
76 | //! namespace rbr::result
77 | //! {
78 | //! template class List, typename Settings> struct values;
79 | //!
80 | //! template class List, typename Settings>
81 | //! using values_t = typename values::type;
82 | //! }
83 | //! @endcode
84 | //!
85 | //! Return the type of a call to rbr::values.
86 | //!
87 | //! ## Example:
88 | //! @include doc/values.cpp
89 | //====================================================================================================================
90 | template class List, typename... Opts>
91 | constexpr auto values(rbr::settings const& s)
92 | {
93 | return result::values_t,List>{ s[typename Opts::keyword_type{}]... };
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/include/raberu/impl/algo/merge.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | namespace rbr
11 | {
12 | //================================================================================================
13 | //! @ingroup stng
14 | //! @related rbr::settings
15 | //! @brief Merge two instances of rbr::settings
16 | //!
17 | //! Merge all options of `opts` and `defs`. If an options is present in both arguments, the one
18 | //! from `opts` is used.
19 | //!
20 | //! @param opts rbr::settings to merge
21 | //! @param defs rbr::settings acting as default value
22 | //! @return An instance of rbr::settings containing all options from `opts` and any options
23 | //! from `defs` not present in `opts`.
24 | //! ## Example:
25 | //! @include doc/merge.cpp
26 | //================================================================================================
27 | template
28 | constexpr auto merge(settings const& opts, settings const& defs) noexcept
29 | {
30 | auto selector = [](K const&, Opts const& o, auto const& d)
31 | {
32 | constexpr K key;
33 | if constexpr( Opts::contains(key) ) return (key = o[key]);
34 | else return (key = d[key]);
35 | };
36 |
37 | auto select = [&](_::keys const&, auto const& os, auto const& ds)
38 | {
39 | return settings(selector(Ks{},os,ds)...);
40 | };
41 |
42 | return select(typename _::uniques<_::keys
43 | ,_::keys
44 | >::type{},opts,defs);
45 | }
46 |
47 | namespace result
48 | {
49 | template
50 | struct merge
51 | {
52 | using type = decltype( rbr::merge(std::declval(),std::declval()) );
53 | };
54 |
55 | template
56 | using merge_t = typename merge::type;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/include/raberu/impl/concepts.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | //======================================================================================================================
15 | //! @namespace rbr::concepts
16 | //! @brief Raberu Concepts namespace
17 | //======================================================================================================================
18 | namespace rbr::concepts
19 | {
20 | //====================================================================================================================
21 | //! @brief Keyword concept
22 | //!
23 | //! A Keyword type is able to be bound to a value as an [Option](@ref rbr::concepts::option)
24 | //====================================================================================================================
25 | template concept keyword = requires( K k )
26 | {
27 | typename K::tag_type;
28 | { K::template accept() } -> stdfix::same_as;
29 | };
30 |
31 | //====================================================================================================================
32 | //! @brief Option concept
33 | //!
34 | //! An Option type can be aggregated in a [Settings](@ref rbr::concepts::settings) and be
35 | //! fetched later
36 | //====================================================================================================================
37 | template concept option = requires( O const& o )
38 | {
39 | { o(typename std::remove_cvref_t::keyword_type{}) }
40 | -> stdfix::same_as::stored_value_type>;
41 | };
42 |
43 | //====================================================================================================================
44 | //! @brief Settings concept
45 | //!
46 | //! A Settings is a group of [Options](@ref rbr::concepts::option)
47 | //====================================================================================================================
48 | template concept settings = requires( S const& s )
49 | {
50 | typename S::rbr_settings;
51 | };
52 |
53 | //====================================================================================================================
54 | //! @brief Exact match concept helper
55 | //!
56 | //! rbr::concepts::exactly is to be used to constraint functions template parameter to be an
57 | //! instantiation of a precise [Keyword](@ref rbr::concepts::keyword)
58 | //====================================================================================================================
59 | template
60 | concept exactly = stdfix::same_as < typename Option::keyword_type
61 | , std::remove_cvref_t
62 | >;
63 | }
64 |
65 | // Internal concepts
66 | namespace rbr::_
67 | {
68 | // Check for check()
69 | template
70 | concept checks_for = requires(K)
71 | {
72 | { K::template check() };
73 | };
74 |
75 | // Checks for identifier
76 | template
77 | concept identifiable = requires(T t)
78 | {
79 | { t.identifier };
80 | };
81 |
82 | // Checks for identifier
83 | template
84 | concept self_identifiable = requires(T t, std::ostream& os)
85 | {
86 | { os << t };
87 | };
88 |
89 | // Checks for display
90 | template
91 | concept displayable = requires(T t, std::ostream& os, V v)
92 | {
93 | { t.display(os,v) };
94 | };
95 |
96 | // Concept to constraint size
97 | template
98 | concept fits = (N <= M);
99 | }
100 |
--------------------------------------------------------------------------------
/include/raberu/impl/helpers.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | #include
11 |
12 | #define RBR_FWD(...) static_cast(__VA_ARGS__)
13 |
14 | // Fix for non-conformant libcpp
15 | namespace rbr::stdfix
16 | {
17 | template
18 | concept is_same_impl = std::is_same_v;
19 |
20 | template
21 | concept same_as = is_same_impl && is_same_impl;
22 | }
23 |
24 | // Helpers for working on list of keys as unique lists - needed by merge and some contains_*
25 | namespace rbr::_
26 | {
27 | template struct keys {};
28 |
29 | template struct contains;
30 |
31 | template
32 | struct contains> : std::bool_constant<(stdfix::same_as || ...)>
33 | {};
34 |
35 | template struct append_if_impl;
36 |
37 | template struct append_if_impl,true>
38 | {
39 | using type = keys;
40 | };
41 |
42 | template struct append_if_impl,false>
43 | {
44 | using type = keys;
45 | };
46 |
47 | template struct append_if;
48 |
49 | template
50 | struct append_if : append_if_impl::value>
51 | {};
52 |
53 | template struct uniques;
54 |
55 | template
56 | struct uniques>
57 | : uniques< typename append_if::type, keys >
58 | {};
59 |
60 | template struct uniques> { using type = K1s; };
61 |
62 | template struct contain_all;
63 |
64 | template
65 | struct contain_all> : std::bool_constant<(contains::value && ...)>
66 | {};
67 |
68 | template struct contain_all> : std::false_type {};
69 | template struct contain_all, K2s > : std::false_type {};
70 | template<> struct contain_all,keys<>> : std::true_type {};
71 |
72 | template
73 | struct is_equivalent : std::bool_constant::value && contain_all::value>
74 | {};
75 | }
76 |
77 | namespace rbr
78 | {
79 | //====================================================================================================================
80 | //! @ingroup utility
81 | //! @brief Lightweight variadic type list
82 | //====================================================================================================================
83 | template struct types {};
84 | }
85 |
--------------------------------------------------------------------------------
/include/raberu/impl/keywords.hpp:
--------------------------------------------------------------------------------
1 | //======================================================================================================================
2 | /*
3 | RABERU - Fancy Parameters Library
4 | Copyright : RABERU Project Contributors
5 | SPDX-License-Identifier: BSL-1.0
6 | */
7 | //======================================================================================================================
8 | #pragma once
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | //======================================================================================================================
15 | //! @defgroup main Main RABERU components
16 | //!
17 | //! @ingroup main
18 | //! @{
19 | //! @defgroup kwds Keywords definitions and handling
20 | //! @brief Functions and types to handle RABERU keywords
21 | //! @}
22 | //======================================================================================================================
23 | namespace rbr
24 | {
25 | //====================================================================================================================
26 | //! @ingroup kwds
27 | //! @brief Callable object wrapper for functional default value
28 | //! @tparam Func Callable object to keep
29 | //====================================================================================================================
30 | template struct call
31 | {
32 | constexpr call(Func f) : callable(f) {}
33 | constexpr auto perform() const { return callable(); }
34 | Func callable;
35 | };
36 |
37 | //====================================================================================================================
38 | //! @ingroup stng
39 | //! @brief Callable object wrapper for functional default value
40 | //! @tparam Keyword Keyword for the option
41 | //! @tparam Value Value stored in the option
42 | //====================================================================================================================
43 | template struct option
44 | {
45 | using stored_value_type = std::decay_t;
46 | using keyword_type = Keyword;
47 |
48 | constexpr stored_value_type operator()(keyword_type const&) const noexcept { return contents; }
49 | stored_value_type contents;
50 | };
51 |
52 | //====================================================================================================================
53 | //! @ingroup kwds
54 | //! @brief Base class for keyword definition
55 | //!
56 | //! rbr::as_keyword provides an CRTP base class for keyword-like types. It is internally used
57 | //! to provide specific keyword constructors but can be used to define user-defined keyword.
58 | //!
59 | //! @tparam Keyword Keyword type being defined
60 | //====================================================================================================================
61 | template struct as_keyword
62 | {
63 | /// Derived keyword type
64 | using tag_type = Keyword;
65 |
66 | /// Keyword comparison
67 | inline constexpr auto operator<=>(as_keyword const&) const noexcept = default;
68 |
69 | //==================================================================================================================
70 | //! @brief Compile-time validation of value
71 | //!
72 | //! When a value is bound to a [Keyword](@ref rbr::concepts::keyword) to form an
73 | //! [Option](@ref rbr::concepts::option), one can validate this binding by checking arbitrary
74 | //! properties on the value type. This is done by the accept() member.
75 | //!
76 | //! If `Keyword` defines a `check` static template member function, it will be called to provide
77 | //! the return value of accept(). Otherwise, true is returned, thus automatically validating any
78 | //! value type.
79 | //!
80 | //! @tparam T Type to validate
81 | //! @return `true` if T is accepted by current keyword, `false` otherwise.
82 | //!
83 | //! ## Example:
84 | //! @snippet doc/accept.cpp Custom Accept
85 | //==================================================================================================================
86 |
87 | template
88 | static constexpr bool accept()
89 | {
90 | if constexpr(stdfix::same_as,as_keyword>) return true;
91 | else if constexpr(_::checks_for) return Keyword::template check();
92 | else return true;
93 | }
94 |
95 | //==================================================================================================================
96 | //! @brief Assignment of a value to a keyword
97 | //!
98 | //! Bind a value to current [Keyword](@ref rbr::concepts::keyword) and returns an instance of
99 | //! an [Option](@ref rbr::concepts::option).
100 | //!
101 | //! @param v Bound value
102 | //! @return An rbr::option binding the keyword to `v`.
103 | //==================================================================================================================
104 | template
105 | constexpr auto operator=(Type&& v) const noexcept requires( accept() )
106 | {
107 | return option{RBR_FWD(v)};
108 | }
109 |
110 | //==================================================================================================================
111 | //! @brief Stream insertion function
112 | //!
113 | //! Display a textual description of current keyword and bound value over an output stream.
114 | //!
115 | //! If `Keyword` defines a `display` member variable, it will be used to perform this display.
116 | //! Otherwise, its value will be displayed along with either a user-defined identifier or its
117 | //! stringified typename.
118 | //!
119 | //! @param os Output stream
120 | //! @param v Value bound to current keyword
121 | //! @return The up-to-date output stream
122 | //!
123 | //! ## Example:
124 | //! @snippet doc/show.cpp Custom Show
125 | //==================================================================================================================
126 | template std::ostream& show(std::ostream& os, V const& v) const
127 | {
128 | if constexpr(_::displayable) return Keyword{}.display(os,v);
129 | else
130 | {
131 | if constexpr(_::identifiable) os << Keyword::identifier;
132 | else os << '[' << _::type.name() << ']';
133 |
134 | return os << " : " << v << " (" << _::type.name() << ')';
135 | }
136 | }
137 |
138 | /// Specify a default value for the keyword
139 | template
140 | constexpr auto operator|(Type&& v) const noexcept requires( accept() )
141 | {
142 | return _::type_or_>{RBR_FWD(v)};
143 | }
144 |
145 | /// Specify a Callable object as a default value for the keyword
146 | template constexpr auto operator|(call&& v) const noexcept
147 | {
148 | return _::type_or_>{RBR_FWD(v)};
149 | }
150 |
151 | //==================================================================================================================
152 | //! @brief Keyword fetching from options set
153 | //!
154 | //! @param o Set of options to inspect
155 | //! @return f current keyword is present in `o...`, return its bound value. Otherwise,
156 | //! returns an instance of rbr::unknown_key.
157 | //!
158 | //! ## Example:
159 | //! @include doc/keyword_fetch.cpp
160 | //==================================================================================================================
161 | template
162 | constexpr decltype(auto) operator()(Os&&... o) const { return fetch(Keyword{}, RBR_FWD(o)...); }
163 | };
164 |
165 | //====================================================================================================================
166 | //! @ingroup kwds
167 | //! @brief Checked keyword
168 | //!
169 | //! A Checked keyword is a keyword that verify if a value's type satisfies a predicates before
170 | //! binding it
171 | //!
172 | //! @tparam ID Unique identifier for the keyword
173 | //! @tparam Checker Unary template meta-function acting as predicate
174 | //====================================================================================================================
175 | template class Checker>
176 | struct checked_keyword : as_keyword>
177 | {
178 | using as_keyword>::operator=;
179 | template static constexpr bool check() { return Checker::value; }
180 |
181 | template
182 | std::ostream& display(std::ostream& os, V const& v) const
183 | {
184 | if constexpr(_::self_identifiable) os << ID{};
185 | else
186 | {
187 | if constexpr(_::identifiable) os << ID::identifier;
188 | else os << '[' << _::type.name() << ']';
189 | }
190 |
191 | os << " ::: " << v << " (" << _::type.name() << ") checked by '";
192 | return os << _::type>.name() << '\'';
193 | }
194 | };
195 |
196 | //====================================================================================================================
197 | //! @ingroup kwds
198 | //! @brief Typed keyword
199 | //!
200 | //! A Typed keyword is a keyword that verify if a value's type is exactly matching a type.
201 | //!
202 | //! @tparam ID Unique identifier for the keyword
203 | //! @tparam Type Type to accept
204 | //====================================================================================================================
205 | template
206 | struct typed_keyword : as_keyword>
207 | {
208 | using as_keyword>::operator=;
209 | template
210 | static constexpr bool check() { return std::is_same_v,Type>; }
211 |
212 | template
213 | std::ostream& display(std::ostream& os, V const& v) const
214 | {
215 | if constexpr(_::self_identifiable) os << ID{};
216 | else
217 | {
218 | if constexpr(_::identifiable) os << ID::identifier;
219 | else os << '[' << _::type.name() << ']';
220 | }
221 |
222 | return os << " : " << v << " of type '" << _::type.name() << '\'';
223 | }
224 | };
225 |
226 | //====================================================================================================================
227 | //! @ingroup kwds
228 | //! @brief Regular keyword
229 | //!
230 | //! A Regular keyword is a keyword that accepts any types.
231 | //!
232 | //! @tparam ID Unique identifier for the keyword
233 | //====================================================================================================================
234 | template
235 | struct any_keyword : as_keyword>
236 | {
237 | using as_keyword>::operator=;
238 |
239 | /// ID type associated to the keyword
240 | using id_type = ID;
241 |
242 | template
243 | std::ostream& display(std::ostream& os, V const& v) const
244 | {
245 | if constexpr(_::self_identifiable) os << ID{};
246 | else
247 | {
248 | if constexpr(_::identifiable) os << ID::identifier;
249 | else os << '[' << _::type.name() << ']';
250 | }
251 |
252 | return os << " : " << v << " (" << _::type.name() << ')';
253 | }
254 | };
255 |
256 | //====================================================================================================================
257 | //! @ingroup kwds
258 | //! @brief Flag keyword
259 | //!
260 | //! A Flag keyword is a keyword which value is given by its mere presence. It accepts no binding
261 | //! and return a value convertible to `bool` when set in a rbr::settings.
262 | //!
263 | //! By design, a flag is also its own rbr::option.
264 | //!
265 | //! @tparam ID Unique identifier for the keyword
266 | //====================================================================================================================
267 | template struct flag_keyword
268 | {
269 | constexpr flag_keyword() {}
270 | constexpr flag_keyword(ID const&) {}
271 |
272 | /// ID type associated to the keyword
273 | using id_type = ID;
274 |
275 | template static constexpr bool accept()
276 | {
277 | return std::is_same_v;
278 | }
279 |
280 | std::ostream& show(std::ostream& os, bool) const
281 | {
282 | if constexpr(_::identifiable) os << ID::identifier;
283 | else if constexpr(_::self_identifiable) os << ID{};
284 | else os << '[' << _::type.name() << ']';
285 |
286 | return os << " : set";
287 | }
288 |
289 | using tag_type = ID;
290 | using keyword_type = flag_keyword;
291 | using stored_value_type = bool;
292 |
293 | template
294 | constexpr auto operator=(Type&&) const noexcept { return *this; }
295 |
296 | template
297 | constexpr auto operator|(Type&& v) const noexcept
298 | {
299 | return _::type_or_>{RBR_FWD(v)};
300 | }
301 |
302 | template constexpr auto operator|(call&& v) const noexcept
303 | {
304 | return _::type_or_>{RBR_FWD(v)};
305 | }
306 |
307 | constexpr auto operator()(keyword_type const&) const noexcept { return true; }
308 |
309 | template
310 | constexpr decltype(auto) operator()(O0&&, O1&&, Os&&... ) const
311 | {
312 | return stdfix::same_as::keyword_type>
313 | || stdfix::same_as