|
2 | 2 | // This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl). |
3 | 3 | // Licensed under the MIT License. See the LICENSE file in the project root for full license information. |
4 | 4 |
|
| 5 | +/// @file gl/io/options_manip.hpp |
| 6 | +/// @brief Defines custom I/O stream manipulators for configuring serialization and deserialization options. |
| 7 | + |
5 | 8 | #pragma once |
6 | 9 |
|
7 | 10 | #include "gl/attributes/force_inline.hpp" |
|
12 | 15 |
|
13 | 16 | namespace gl::io { |
14 | 17 |
|
| 18 | +/// @ingroup GL GL-IO |
| 19 | +/// @brief Type used for standard I/O stream custom index allocation (`std::ios_base::xalloc`). |
15 | 20 | using index_type = int; |
| 21 | + |
| 22 | +/// @ingroup GL GL-IO |
| 23 | +/// @brief Type used for storing custom option flags within standard I/O streams. |
16 | 24 | using iword_type = long; |
| 25 | + |
| 26 | +/// @ingroup GL GL-IO |
| 27 | +/// @brief Type representing the zero-indexed position of a specific option bit. |
17 | 28 | using bit_position_type = unsigned; |
18 | 29 |
|
| 30 | +/// @ingroup GL GL-IO |
| 31 | +/// @brief Base bit representing the first position in an `iword` flag map. |
19 | 32 | inline constexpr iword_type iword_bit = 1ul; |
20 | 33 |
|
| 34 | +/// @ingroup GL GL-IO |
| 35 | +/// @brief A custom stream manipulator for modifying formatting options on standard I/O streams. |
| 36 | +/// |
| 37 | +/// Utilizing `std::ios_base::xalloc` and the `iword` map, this class safely injects custom formatting |
| 38 | +/// state directly into C++ standard streams. It acts as an intermediate proxy object produced by |
| 39 | +/// functions like @ref gl::io::set_options "set_options" and @ref gl::io::clear_options "clear_options". |
21 | 40 | class options_manip { |
22 | 41 | public: |
| 42 | + /// @brief Default constructor is disabled. |
23 | 43 | options_manip() = delete; |
24 | 44 |
|
| 45 | + /// @brief Constructs a manipulator with specific state masks. |
| 46 | + /// @param set_mask The bitmask of options to enable. |
| 47 | + /// @param clear_mask The bitmask of options to disable (defaults to 0). |
25 | 48 | constexpr explicit options_manip(iword_type set_mask, iword_type clear_mask = 0ul) |
26 | 49 | : _set_mask(set_mask), _clear_mask(clear_mask) {} |
27 | 50 |
|
| 51 | + /// @brief Applies the manipulator's formatting masks to an output stream. |
| 52 | + /// @param os The target output stream. |
| 53 | + /// @param manip The manipulator containing the masks to apply. |
| 54 | + /// @return The stream reference for chaining. |
28 | 55 | friend std::ostream& operator<<(std::ostream& os, const options_manip& manip) { |
29 | 56 | os.iword(_iostream_property_map_index()) &= ~manip._clear_mask; |
30 | 57 | os.iword(_iostream_property_map_index()) |= manip._set_mask; |
31 | 58 | return os; |
32 | 59 | } |
33 | 60 |
|
| 61 | + /// @brief Applies the manipulator's formatting masks to an input stream. |
| 62 | + /// @param is The target input stream. |
| 63 | + /// @param manip The manipulator containing the masks to apply. |
| 64 | + /// @return The stream reference for chaining. |
34 | 65 | friend std::istream& operator>>(std::istream& is, const options_manip& manip) { |
35 | 66 | is.iword(_iostream_property_map_index()) &= ~manip._clear_mask; |
36 | 67 | is.iword(_iostream_property_map_index()) |= manip._set_mask; |
37 | 68 | return is; |
38 | 69 | } |
39 | 70 |
|
| 71 | + /// @brief Checks if a specific option bit is currently enabled on the given stream. |
| 72 | + /// @param stream The stream to check. |
| 73 | + /// @param bit_position The numeric position of the bit to verify. |
| 74 | + /// @return `true` if the specified bit is set, `false` otherwise. |
40 | 75 | [[nodiscard]] gl_attr_force_inline static bool is_option_set( |
41 | 76 | std::ios_base& stream, bit_position_type bit_position |
42 | 77 | ) { |
43 | 78 | return (stream.iword(_iostream_property_map_index()) & (iword_bit << bit_position)) != 0; |
44 | 79 | } |
45 | 80 |
|
| 81 | + /// @brief Checks if a specific enum-based option is currently enabled on the given stream. |
| 82 | + /// @param stream The stream to check. |
| 83 | + /// @param bit The scoped enum value representing the bit to verify. |
| 84 | + /// @return `true` if the specified bit is set, `false` otherwise. |
46 | 85 | [[nodiscard]] gl_attr_force_inline static bool is_option_set( |
47 | 86 | std::ios_base& stream, traits::c_enum auto bit |
48 | 87 | ) { |
49 | 88 | return is_option_set(stream, static_cast<bit_position_type>(bit)); |
50 | 89 | } |
51 | 90 |
|
| 91 | + /// @brief Checks if a specific sequence of bits matches the exact stream state. |
| 92 | + /// @param stream The stream to check. |
| 93 | + /// @param bitmask The bitmask to verify against the stream's state. |
| 94 | + /// @return `true` if all bits within the mask are strictly set, `false` otherwise. |
52 | 95 | [[nodiscard]] gl_attr_force_inline static bool are_options_set( |
53 | 96 | std::ios_base& stream, iword_type bitmask |
54 | 97 | ) { |
@@ -86,47 +129,94 @@ template <typename T> |
86 | 129 |
|
87 | 130 | } // namespace detail |
88 | 131 |
|
| 132 | +/// @ingroup GL GL-IO |
| 133 | +/// @brief Creates a stream manipulator that enables the specified option bits. |
| 134 | +/// @tparam Args Variadic template arguments representing the bits to set. |
| 135 | +/// @param bits The specific options/bits to enable. |
| 136 | +/// @return An @ref gl::io::options_manip "options_manip" object ready to be piped into a stream. |
89 | 137 | template <typename... Args> |
90 | 138 | [[nodiscard]] constexpr options_manip set_options(Args... bits) { |
91 | 139 | return options_manip{detail::build_mask(bits...), 0ul}; |
92 | 140 | } |
93 | 141 |
|
| 142 | +/// @ingroup GL GL-IO |
| 143 | +/// @brief Creates a stream manipulator that enables the specified option bits from a list. |
| 144 | +/// @tparam T The type of the bits. |
| 145 | +/// @param bits An initializer list containing the options/bits to enable. |
| 146 | +/// @return An @ref gl::io::options_manip "options_manip" object ready to be piped into a stream. |
94 | 147 | template <typename T> |
95 | 148 | [[nodiscard]] constexpr options_manip set_options(std::initializer_list<T> bits) { |
96 | 149 | return options_manip{detail::build_mask_from(bits), 0ul}; |
97 | 150 | } |
98 | 151 |
|
| 152 | +/// @ingroup GL GL-IO |
| 153 | +/// @brief Creates a stream manipulator that disables the specified option bits. |
| 154 | +/// @tparam Args Variadic template arguments representing the bits to clear. |
| 155 | +/// @param bits The specific options/bits to disable. |
| 156 | +/// @return An @ref gl::io::options_manip "options_manip" object ready to be piped into a stream. |
99 | 157 | template <typename... Args> |
100 | 158 | [[nodiscard]] constexpr options_manip clear_options(Args... bits) { |
101 | 159 | return options_manip{0ul, detail::build_mask(bits...)}; |
102 | 160 | } |
103 | 161 |
|
| 162 | +/// @ingroup GL GL-IO |
| 163 | +/// @brief Creates a stream manipulator that disables the specified option bits from a list. |
| 164 | +/// @tparam T The type of the bits. |
| 165 | +/// @param bits An initializer list containing the options/bits to disable. |
| 166 | +/// @return An @ref gl::io::options_manip "options_manip" object ready to be piped into a stream. |
104 | 167 | template <typename T> |
105 | 168 | [[nodiscard]] constexpr options_manip clear_options(std::initializer_list<T> bits) { |
106 | 169 | return options_manip{0ul, detail::build_mask_from(bits)}; |
107 | 170 | } |
108 | 171 |
|
| 172 | +/// @ingroup GL GL-IO |
| 173 | +/// @brief Convenience wrapper to check if a specific option bit is set on the stream. |
| 174 | +/// @param stream The stream to check. |
| 175 | +/// @param bit_position The numeric position of the bit to verify. |
| 176 | +/// @return `true` if the specified bit is set, `false` otherwise. |
109 | 177 | [[nodiscard]] gl_attr_force_inline bool is_option_set( |
110 | 178 | std::ios_base& stream, bit_position_type bit_position |
111 | 179 | ) { |
112 | 180 | return options_manip::is_option_set(stream, bit_position); |
113 | 181 | } |
114 | 182 |
|
| 183 | +/// @ingroup GL GL-IO |
| 184 | +/// @brief Convenience wrapper to check if a specific enum-based option is set on the stream. |
| 185 | +/// @param stream The stream to check. |
| 186 | +/// @param bit The scoped enum value representing the bit to verify. |
| 187 | +/// @return `true` if the specified bit is set, `false` otherwise. |
115 | 188 | [[nodiscard]] gl_attr_force_inline bool is_option_set( |
116 | 189 | std::ios_base& stream, traits::c_enum auto bit |
117 | 190 | ) { |
118 | 191 | return options_manip::is_option_set(stream, bit); |
119 | 192 | } |
120 | 193 |
|
| 194 | +/// @ingroup GL GL-IO |
| 195 | +/// @brief Convenience wrapper to check if a combined bitmask of options is set on the stream. |
| 196 | +/// @param stream The stream to check. |
| 197 | +/// @param bitmask The exact bitmask to verify. |
| 198 | +/// @return `true` if all bits within the mask are strictly set, `false` otherwise. |
121 | 199 | [[nodiscard]] gl_attr_force_inline bool are_options_set(std::ios_base& stream, iword_type bitmask) { |
122 | 200 | return options_manip::are_options_set(stream, bitmask); |
123 | 201 | } |
124 | 202 |
|
| 203 | +/// @ingroup GL GL-IO |
| 204 | +/// @brief Convenience wrapper to check if multiple specific options are simultaneously set. |
| 205 | +/// @tparam Args Variadic template arguments representing the bits. |
| 206 | +/// @param stream The stream to check. |
| 207 | +/// @param bits The specific options/bits to verify. |
| 208 | +/// @return `true` if all specified bits are set, `false` otherwise. |
125 | 209 | template <typename... Args> |
126 | 210 | [[nodiscard]] gl_attr_force_inline bool are_options_set(std::ios_base& stream, Args... bits) { |
127 | 211 | return options_manip::are_options_set(stream, detail::build_mask(bits...)); |
128 | 212 | } |
129 | 213 |
|
| 214 | +/// @ingroup GL GL-IO |
| 215 | +/// @brief Convenience wrapper to check if multiple specific options from a list are simultaneously set. |
| 216 | +/// @tparam T The type of the elements in the initializer list. |
| 217 | +/// @param stream The stream to check. |
| 218 | +/// @param bits An initializer list containing the options/bits to verify. |
| 219 | +/// @return `true` if all specified bits are set, `false` otherwise. |
130 | 220 | template <typename T> |
131 | 221 | [[nodiscard]] gl_attr_force_inline bool are_options_set( |
132 | 222 | std::ios_base& stream, std::initializer_list<T> bits |
|
0 commit comments