Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:39:19

0001 //
0002 // Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_MYSQL_ANY_ADDRESS_HPP
0009 #define BOOST_MYSQL_ANY_ADDRESS_HPP
0010 
0011 #include <boost/mysql/defaults.hpp>
0012 #include <boost/mysql/string_view.hpp>
0013 
0014 #include <boost/mysql/detail/access.hpp>
0015 
0016 #include <string>
0017 
0018 namespace boost {
0019 namespace mysql {
0020 
0021 /// The type of an address identifying a MySQL server.
0022 enum class address_type
0023 {
0024     /// An Internet hostname and a TCP port.
0025     host_and_port,
0026 
0027     /// A UNIX domain socket path.
0028     unix_path
0029 };
0030 
0031 /**
0032  * \brief A host and port identifying how to connect to a MySQL server.
0033  * \details
0034  * This is an owning type with value semantics.
0035  */
0036 struct host_and_port
0037 {
0038     /**
0039      * \brief The hostname where the MySQL server is expected to be listening.
0040      * \details
0041      * An empty string is equivalent to `localhost`. This is the default.
0042      * This is an owning field
0043      */
0044     std::string host;
0045 
0046     /// The port where the MySQL server is expected to be listening.
0047     unsigned short port{default_port};
0048 };
0049 
0050 /**
0051  * \brief Contains a UNIX-socket domain path.
0052  * \details
0053  * This type is defined in all systems, regardless of their UNIX socket support.
0054  * \n
0055  * This is an owning type with value semantics.
0056  */
0057 struct unix_path
0058 {
0059     /**
0060      * \brief The UNIX domain socket path where the MySQL server is listening.
0061      * \details Defaults to the empty string. This is an owning field.
0062      */
0063     std::string path;
0064 };
0065 
0066 /**
0067  * \brief A server address, identifying how to physically connect to a MySQL server.
0068  * \details
0069  * A variant-like type that can represent the network address of a MySQL server,
0070  * regardless of the transport type being used. It can contain either a host
0071  * and port (to connect using TCP) or a UNIX path (to connect using UNIX domain sockets).
0072  * \n
0073  * This class may be extended in the future to accommodate Windows named pipes.
0074  * \n
0075  * This type has value semantics: it is owning and regular.
0076  */
0077 class any_address
0078 {
0079 #ifndef BOOST_MYSQL_DOXYGEN
0080     struct
0081     {
0082         address_type type;
0083         std::string address;
0084         unsigned short port;
0085     } impl_;
0086 
0087     any_address(address_type t, std::string&& addr, unsigned short port) noexcept
0088         : impl_{t, std::move(addr), port}
0089     {
0090     }
0091     friend struct detail::access;
0092 #endif
0093 
0094 public:
0095     /**
0096      * \brief Constructs an empty address.
0097      * \details Results in an address with `this->type() == address_type::host_and_port`,
0098      * `this->hostname() == ""` and `this->port() == default_port`, which identifies
0099      * a server running on `localhost` using the default port.
0100      * \par Exception safety
0101      * No-throw guarantee.
0102      */
0103     any_address() noexcept : any_address(address_type::host_and_port, std::string(), default_port) {}
0104 
0105     /**
0106      * \brief Copy constructor.
0107      * \par Exception safety
0108      * Strong guarantee. Exceptions may be thrown by memory allocations.
0109      * \par Object lifetimes
0110      * `*this` and `other` will have independent lifetimes (regular value semantics).
0111      */
0112     any_address(const any_address& other) = default;
0113 
0114     /**
0115      * \brief Move constructor.
0116      * \details Leaves `other` in a valid but unspecified state.
0117      * \par Exception safety
0118      * No-throw guarantee.
0119      */
0120     any_address(any_address&& other) = default;
0121 
0122     /**
0123      * \brief Copy assignment.
0124      * \par Exception safety
0125      * Basic guarantee. Exceptions may be thrown by memory allocations.
0126      * \par Object lifetimes
0127      * `*this` and `other` will have independent lifetimes (regular value semantics).
0128      */
0129     any_address& operator=(const any_address& other) = default;
0130 
0131     /**
0132      * \brief Move assignment.
0133      * \details Leaves `other` in a valid but unspecified state.
0134      * \par Exception safety
0135      * No-throw guarantee.
0136      */
0137     any_address& operator=(any_address&& other) = default;
0138 
0139     /// Destructor.
0140     ~any_address() = default;
0141 
0142     /**
0143      * \brief Constructs an address containing a host and a port.
0144      * \details Results in an address with `this->type() == address_type::host_and_port`,
0145      * `this->hostname() == value.hostname()` and `this->port() == value.port()`.
0146      *
0147      * \par Object lifetimes
0148      * `*this` and `value` will have independent lifetimes (regular value semantics).
0149      *
0150      * \par Exception safety
0151      * No-throw guarantee.
0152      */
0153     any_address(host_and_port value) noexcept
0154         : impl_{address_type::host_and_port, std::move(value.host), value.port}
0155     {
0156     }
0157 
0158     /**
0159      * \brief Constructs an address containing a UNIX socket path.
0160      * \details Results in an address with `this->type() == address_type::unix_path`,
0161      * `this->unix_socket_path() == value.path()`.
0162      *
0163      * \par Object lifetimes
0164      * `*this` and `value` will have independent lifetimes (regular value semantics).
0165      *
0166      * \par Exception safety
0167      * No-throw guarantee.
0168      */
0169     any_address(unix_path value) noexcept : impl_{address_type::unix_path, std::move(value.path), 0} {}
0170 
0171     /**
0172      * \brief Retrieves the type of address that this object contains.
0173      * \par Exception safety
0174      * No-throw guarantee.
0175      */
0176     address_type type() const noexcept { return impl_.type; }
0177 
0178     /**
0179      * \brief Retrieves the hostname that this object contains.
0180      * \par Preconditions
0181      * `this->type() == address_type::host_and_port`
0182      *
0183      * \par Object lifetimes
0184      * The returned view points into `*this`, and is valid as long as `*this`
0185      * is alive and hasn't been assigned to or moved from.
0186      *
0187      * \par Exception safety
0188      * No-throw guarantee.
0189      */
0190     string_view hostname() const noexcept
0191     {
0192         BOOST_ASSERT(type() == address_type::host_and_port);
0193         return impl_.address;
0194     }
0195 
0196     /**
0197      * \brief Retrieves the port that this object contains.
0198      * \par Preconditions
0199      * `this->type() == address_type::host_and_port`
0200      *
0201      * \par Exception safety
0202      * No-throw guarantee.
0203      */
0204     unsigned short port() const noexcept
0205     {
0206         BOOST_ASSERT(type() == address_type::host_and_port);
0207         return impl_.port;
0208     }
0209 
0210     /**
0211      * \brief Retrieves the UNIX socket path that this object contains.
0212      * \par Preconditions
0213      * `this->type() == address_type::unix_path`
0214      *
0215      * \par Object lifetimes
0216      * The returned view points into `*this`, and is valid as long as `*this`
0217      * is alive and hasn't been assigned to or moved from.
0218      *
0219      * \par Exception safety
0220      * No-throw guarantee.
0221      */
0222     string_view unix_socket_path() const noexcept
0223     {
0224         BOOST_ASSERT(type() == address_type::unix_path);
0225         return impl_.address;
0226     }
0227 
0228     /**
0229      * \brief Replaces the current object with a host and port.
0230      * \details
0231      * Destroys the current contained object and constructs a new
0232      * host and port from the passed components. This function can
0233      * change the underlying type of object held by `*this`.
0234      * \n
0235      * The constructed object has `this->type() == address_type::host_and_port`,
0236      * `this->hostname() == hostname` and `this->port() == port`.
0237      * \n
0238      * An empty hostname is equivalent to `localhost`.
0239      * \n
0240      * \par Exception safety
0241      * Basic guarantee. Memory allocations may throw.
0242      * \par Object lifetimes
0243      * Invalidates views pointing into `*this`.
0244      */
0245     void emplace_host_and_port(std::string hostname, unsigned short port = default_port)
0246     {
0247         impl_.type = address_type::host_and_port;
0248         impl_.address = std::move(hostname);
0249         impl_.port = port;
0250     }
0251 
0252     /**
0253      * \brief Replaces the current object with a UNIX socket path.
0254      * \details
0255      * Destroys the current contained object and constructs a new
0256      * UNIX socket path from the passed value. This function can
0257      * change the underlying type of object held by `*this`.
0258      * \n
0259      * The constructed object has `this->type() == address_type::unix_path` and
0260      * `this->unix_socket_path() == path`.
0261      * \n
0262      * \par Exception safety
0263      * Basic guarantee. Memory allocations may throw.
0264      * \par Object lifetimes
0265      * Invalidates views pointing into `*this`.
0266      */
0267     void emplace_unix_path(std::string path)
0268     {
0269         impl_.type = address_type::unix_path;
0270         impl_.address = std::move(path);
0271         impl_.port = 0;
0272     }
0273 
0274     /**
0275      * \brief Tests for equality.
0276      * \details Two addresses are equal if they have the same type and individual components.
0277      * \par Exception safety
0278      * No-throw guarantee.
0279      */
0280     bool operator==(const any_address& rhs) const noexcept
0281     {
0282         return impl_.type == rhs.impl_.type && impl_.address == rhs.impl_.address &&
0283                impl_.port == rhs.impl_.port;
0284     }
0285 
0286     /**
0287      * \brief Tests for inequality.
0288      * \par Exception safety
0289      * No-throw guarantee.
0290      */
0291     bool operator!=(const any_address& rhs) const noexcept { return !(*this == rhs); }
0292 };
0293 
0294 }  // namespace mysql
0295 }  // namespace boost
0296 
0297 #endif