include/boost/corosio/ipv4_address.hpp

100.0% Lines (11/0/11) 100.0% List of functions (6/0/6)
ipv4_address.hpp
f(x) Functions (6)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_IPV4_ADDRESS_HPP
11 #define BOOST_COROSIO_IPV4_ADDRESS_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14
15 #include <boost/capy/io_result.hpp>
16
17 #include <array>
18 #include <cstdint>
19 #include <iosfwd>
20 #include <string>
21 #include <string_view>
22 #include <system_error>
23
24 namespace boost::corosio {
25
26 /** An IP version 4 style address.
27
28 Objects of this type are used to construct,
29 parse, and manipulate IP version 4 addresses.
30
31 @par BNF
32 @code
33 IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
34
35 dec-octet = DIGIT ; 0-9
36 / %x31-39 DIGIT ; 10-99
37 / "1" 2DIGIT ; 100-199
38 / "2" %x30-34 DIGIT ; 200-249
39 / "25" %x30-35 ; 250-255
40 @endcode
41
42 @par Specification
43 @li <a href="https://en.wikipedia.org/wiki/IPv4">IPv4 (Wikipedia)</a>
44 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
45 >3.2.2. Host (rfc3986)</a>
46
47 @see
48 @ref make_ipv4_address,
49 @ref ipv6_address.
50 */
51 class BOOST_COROSIO_DECL ipv4_address
52 {
53 std::uint32_t addr_ = 0;
54
55 public:
56 /** The number of characters in the longest possible IPv4 string.
57
58 The longest IPv4 address string is "255.255.255.255".
59 */
60 static constexpr std::size_t max_str_len = 15;
61
62 /** The type used to represent an address as an unsigned integer.
63 */
64 using uint_type = std::uint32_t;
65
66 /** The type used to represent an address as an array of bytes.
67 */
68 using bytes_type = std::array<unsigned char, 4>;
69
70 /** Default constructor.
71
72 Constructs the unspecified address (0.0.0.0).
73 */
74 225542x ipv4_address() = default;
75
76 /** Copy constructor.
77 */
78 ipv4_address(ipv4_address const&) = default;
79
80 /** Copy assignment.
81
82 @return A reference to this object.
83 */
84 ipv4_address& operator=(ipv4_address const&) = default;
85
86 /** Construct from an unsigned integer.
87
88 This function constructs an address from
89 the unsigned integer `u`, where the most
90 significant byte forms the first octet
91 of the resulting address.
92
93 @param u The integer to construct from.
94 */
95 explicit ipv4_address(uint_type u) noexcept;
96
97 /** Construct from an array of bytes.
98
99 This function constructs an address
100 from the array in `bytes`, which is
101 interpreted in big-endian.
102
103 @param bytes The value to construct from.
104 */
105 explicit ipv4_address(bytes_type const& bytes) noexcept;
106
107 /** Construct from a string.
108
109 This function constructs an address from
110 the string `s`, which must contain a valid
111 IPv4 address string or else an exception
112 is thrown.
113
114 @note For a non-throwing parse function,
115 use @ref make_ipv4_address.
116
117 @par Exception Safety
118 Exceptions thrown on invalid input.
119
120 @throws std::system_error `errc::invalid_argument` if the input
121 failed to parse correctly.
122
123 @param s The string to parse.
124
125 @par Specification
126 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
127 >3.2.2. Host (rfc3986)</a>
128
129 @see
130 @ref make_ipv4_address.
131 */
132 explicit ipv4_address(std::string_view s);
133
134 /** Return the address as bytes, in network byte order.
135
136 @return The address as an array of bytes.
137 */
138 bytes_type to_bytes() const noexcept;
139
140 /** Return the address as an unsigned integer.
141
142 @return The address as an unsigned integer.
143 */
144 uint_type to_uint() const noexcept;
145
146 /** Return the address as a string in dotted decimal format.
147
148 @par Example
149 @code
150 assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
151 @endcode
152
153 @return The address as a string.
154 */
155 std::string to_string() const;
156
157 /** Write a dotted decimal string representing the address to a buffer.
158
159 The resulting buffer is not null-terminated.
160
161 @throw std::length_error `dest_size < ipv4_address::max_str_len`
162
163 @return The formatted string view.
164
165 @param dest The buffer in which to write,
166 which must have at least `dest_size` space.
167
168 @param dest_size The size of the output buffer.
169 */
170 std::string_view to_buffer(char* dest, std::size_t dest_size) const;
171
172 /** Return true if the address is a loopback address.
173
174 @return `true` if the address is a loopback address.
175 */
176 bool is_loopback() const noexcept;
177
178 /** Return true if the address is unspecified.
179
180 @return `true` if the address is unspecified.
181 */
182 bool is_unspecified() const noexcept;
183
184 /** Return true if the address is a multicast address.
185
186 @return `true` if the address is a multicast address.
187 */
188 bool is_multicast() const noexcept;
189
190 /** Return true if two addresses are equal.
191
192 @return `true` if the addresses are equal, otherwise `false`.
193 */
194 friend bool
195 125x operator==(ipv4_address const& a1, ipv4_address const& a2) noexcept
196 {
197 125x return a1.addr_ == a2.addr_;
198 }
199
200 /** Return true if two addresses are not equal.
201
202 @return `true` if the addresses are not equal, otherwise `false`.
203 */
204 friend bool
205 2x operator!=(ipv4_address const& a1, ipv4_address const& a2) noexcept
206 {
207 2x return a1.addr_ != a2.addr_;
208 }
209
210 /** Return an address object that represents any address.
211
212 @return The any address (0.0.0.0).
213 */
214 225448x static ipv4_address any() noexcept
215 {
216 225448x return ipv4_address();
217 }
218
219 /** Return an address object that represents the loopback address.
220
221 @return The loopback address (127.0.0.1).
222 */
223 7551x static ipv4_address loopback() noexcept
224 {
225 7551x return ipv4_address(0x7F000001);
226 }
227
228 /** Return an address object that represents the broadcast address.
229
230 @return The broadcast address (255.255.255.255).
231 */
232 3x static ipv4_address broadcast() noexcept
233 {
234 3x return ipv4_address(0xFFFFFFFF);
235 }
236
237 /** Format the address to an output stream.
238
239 IPv4 addresses written to output streams
240 are written in their dotted decimal format.
241
242 @param os The output stream.
243 @param addr The address to format.
244 @return The output stream.
245 */
246 friend BOOST_COROSIO_DECL std::ostream&
247 operator<<(std::ostream& os, ipv4_address const& addr);
248
249 private:
250 friend class ipv6_address;
251
252 std::size_t print_impl(char* dest) const noexcept;
253 };
254
255 /** Create an IPv4 address from an IP address string in dotted decimal form.
256
257 @param s The string to parse.
258 @return The error code, empty on success, and the parsed
259 address — default-constructed on failure.
260 */
261 [[nodiscard]] BOOST_COROSIO_DECL capy::io_result<ipv4_address>
262 make_ipv4_address(std::string_view s) noexcept;
263
264 } // namespace boost::corosio
265
266 #endif
267