AsyncBerkeley
Asynchronous Berkeley sockets. Simple.
Loading...
Searching...
No Matches
socket_option.hpp
Go to the documentation of this file.
1/* Copyright 2025 Kevin Exton
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
20#pragma once
21#ifndef IO_SOCKET_OPTION_HPP
22#define IO_SOCKET_OPTION_HPP
23#include <cassert>
24#include <cstring>
25#include <span>
26#include <type_traits>
27namespace io::socket {
33template <typename T>
34 requires std::is_trivially_copyable_v<T>
36public:
38 using value_type = std::decay_t<T>;
40 using size_type = std::size_t;
41
47 template <size_type Size = sizeof(value_type)>
48 requires(Size <= sizeof(value_type))
49 constexpr socket_option(size_type size = Size) noexcept : size_{size}
50 {}
51
53 socket_option(const socket_option &) = default;
56
61 socket_option(const value_type &val) noexcept : size_{sizeof(val)}
62 {
63 std::memcpy(storage_.data(), &val, size_);
64 }
65
71 template <size_type Size>
72 requires(Size <= sizeof(value_type) || Size == std::dynamic_extent)
73 socket_option(std::span<const std::byte, Size> option) noexcept
74 : size_{option.size()}
75 {
76 assert(option.size() <= sizeof(value_type) &&
77 "option.size() must be <= sizeof(value_type)");
78 assert(option.size() > 0 && option.data() != nullptr &&
79 "If option.size() > 0 then option.data() must not be NULL.");
80 std::memcpy(storage_.data(), option.data(), size_);
81 }
82
88 template <size_type Size>
89 requires(Size <= sizeof(value_type) || Size == std::dynamic_extent)
90 socket_option(std::span<std::byte, Size> option) noexcept
91 : socket_option(std::span<const std::byte, Size>(option))
92 {}
93
98 auto operator=(const socket_option &) -> socket_option & = default;
99
104 auto operator=(socket_option &&) -> socket_option & = default;
105
107 ~socket_option() = default;
108
113 [[nodiscard]] constexpr auto operator*() noexcept -> value_type &
114 {
115 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
116 return *reinterpret_cast<value_type *>(storage_.data());
117 }
118
123 [[nodiscard]] constexpr auto operator->() noexcept -> value_type *
124 {
125 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
126 return reinterpret_cast<value_type *>(storage_.data());
127 }
128
134 [[nodiscard]] constexpr auto begin() noexcept -> std::byte *
135 {
136 return storage_.begin();
137 }
138
144 [[nodiscard]] constexpr auto begin() const noexcept -> const std::byte *
145 {
146 return storage_.cbegin();
147 }
148
153 [[nodiscard]] constexpr auto end() noexcept -> std::byte *
154 {
155 return storage_.begin() + size_;
156 }
157
163 [[nodiscard]] constexpr auto end() const noexcept -> const std::byte *
164 {
165 return storage_.cbegin() + size_;
166 }
167
174 auto
175 operator<=>(const socket_option &other) const noexcept -> std::strong_ordering
176 {
177 using std::memcmp;
178 return (size_ == other.size_)
179 ? memcmp(storage_.data(), other.storage_.data(), size_) <=> 0
180 : size_ <=> other.size_;
181 }
182
188 auto operator==(const socket_option &other) const noexcept -> bool
189 {
190 return size_ == other.size_ &&
191 std::memcmp(storage_.data(), other.storage_.data(), size_) == 0;
192 }
193
194private:
196 std::array<std::byte, sizeof(value_type)> storage_{};
198 size_type size_{sizeof(value_type)};
199};
200
201} // namespace io::socket
202#endif // IO_SOCKET_OPTION_HPP
A generic wrapper for socket options.
Definition socket_option.hpp:35
auto operator<=>(const socket_option &other) const noexcept -> std::strong_ordering
Compares this socket_option with another for ordering.
Definition socket_option.hpp:175
auto operator=(const socket_option &) -> socket_option &=default
Default copy assignment operator.
constexpr auto begin() const noexcept -> const std::byte *
Gets a const iterator to the beginning of the option's byte representation.
Definition socket_option.hpp:144
socket_option(const socket_option &)=default
Default copy constructor.
constexpr auto end() noexcept -> std::byte *
Gets an iterator to the end of the option's byte representation.
Definition socket_option.hpp:153
socket_option(const value_type &val) noexcept
Constructs a socket_option from a value.
Definition socket_option.hpp:61
constexpr auto end() const noexcept -> const std::byte *
Gets a const iterator to the end of the option's byte representation.
Definition socket_option.hpp:163
constexpr auto operator->() noexcept -> value_type *
Accesses the socket option's value.
Definition socket_option.hpp:123
constexpr auto operator*() noexcept -> value_type &
Dereferences the socket option to its value.
Definition socket_option.hpp:113
std::size_t size_type
The size type for the socket option.
Definition socket_option.hpp:40
auto operator=(socket_option &&) -> socket_option &=default
Default move assignment operator.
constexpr auto begin() noexcept -> std::byte *
Gets an iterator to the beginning of the option's byte representation.
Definition socket_option.hpp:134
std::decay_t< T > value_type
The type of the socket option value.
Definition socket_option.hpp:38
auto operator==(const socket_option &other) const noexcept -> bool
Compares two socket_option objects for equality.
Definition socket_option.hpp:188
~socket_option()=default
Default destructor.
socket_option(socket_option &&)=default
Default move constructor.
The io::socket namespace provides a cross-platform abstraction for socket-level I/O operations.
Definition poll_multiplexer.hpp:36