gnss-sim/3rdparty/boost/mysql/any_address.hpp

304 lines
9.1 KiB
C++

//
// Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_MYSQL_ANY_ADDRESS_HPP
#define BOOST_MYSQL_ANY_ADDRESS_HPP
#include <boost/mysql/defaults.hpp>
#include <boost/mysql/string_view.hpp>
#include <boost/mysql/detail/access.hpp>
#include <string>
namespace boost {
namespace mysql {
/// (EXPERIMENTAL) The type of an address identifying a MySQL server.
enum class address_type
{
/// An Internet hostname and a TCP port.
host_and_port,
/// A UNIX domain socket path.
unix_path
};
/**
* \brief (EXPERIMENTAL) A host and port identifying how to connect to a MySQL server.
* \details
* This is an owning type with value semantics.
* \see any_address
*
* \par Experimental
* This part of the API is experimental, and may change in successive
* releases without previous notice.
*/
struct host_and_port
{
/**
* \brief The hostname where the MySQL server is expected to be listening.
* \details
* An empty string is equivalent to `localhost`. This is the default.
* This is an owning field
*/
std::string host;
/// The port where the MySQL server is expected to be listening.
unsigned short port{default_port};
};
/**
* \brief (EXPERIMENTAL) Contains a UNIX-socket domain path.
* \details
* This type is defined in all systems, regardless of their UNIX socket support.
* \n
* This is an owning type with value semantics.
* \see any_address
*/
struct unix_path
{
/**
* \brief The UNIX domain socket path where the MySQL server is listening.
* \details Defaults to the empty string. This is an owning field.
*/
std::string path;
};
/**
* \brief (EXPERIMENTAL) A server address, identifying how to physically connect to a MySQL server.
* \details
* A variant-like type that can represent the network address of a MySQL server,
* regardless of the transport type being used. It can contain either a host
* and port (to connect using TCP) or a UNIX path (to connect using UNIX domain sockets).
* \n
* This class may be extended in the future to accomodate Windows named pipes.
* \n
* This type has value semantics: it is owning and regular.
*/
class any_address
{
#ifndef BOOST_MYSQL_DOXYGEN
struct
{
address_type type;
std::string address;
unsigned short port;
} impl_;
any_address(address_type t, std::string&& addr, unsigned short port) noexcept
: impl_{t, std::move(addr), port}
{
}
friend struct detail::access;
#endif
public:
/**
* \brief Constructs an empty address.
* \details Results in an address with `this->type() == address_type::host_and_port`,
* `this->hostname() == ""` and `this->port() == default_port`, which identifies
* a server running on `localhost` using the default port.
* \par Exception safety
* No-throw guarantee.
*/
any_address() noexcept : any_address(address_type::host_and_port, std::string(), default_port) {}
/**
* \brief Copy constructor.
* \par Exception safety
* Strong guarantee. Exceptions may be thrown by memory allocations.
* \par Object lifetimes
* `*this` and `other` will have independent lifetimes (regular value semantics).
*/
any_address(const any_address& other) = default;
/**
* \brief Move constructor.
* \details Leaves `other` in a valid but unspecified state.
* \par Exception safety
* No-throw guarantee.
*/
any_address(any_address&& other) = default;
/**
* \brief Copy assignment.
* \par Exception safety
* Basic guarantee. Exceptions may be thrown by memory allocations.
* \par Object lifetimes
* `*this` and `other` will have independent lifetimes (regular value semantics).
*/
any_address& operator=(const any_address& other) = default;
/**
* \brief Move assignment.
* \details Leaves `other` in a valid but unspecified state.
* \par Exception safety
* No-throw guarantee.
*/
any_address& operator=(any_address&& other) = default;
/// Destructor.
~any_address() = default;
/**
* \brief Constructs an address containing a host and a port.
* \details Results in an address with `this->type() == address_type::host_and_port`,
* `this->hostname() == value.hostname()` and `this->port() == value.port()`.
*
* \par Object lifetimes
* `*this` and `value` will have independent lifetimes (regular value semantics).
*
* \par Exception safety
* No-throw guarantee.
*/
any_address(host_and_port value) noexcept
: impl_{address_type::host_and_port, std::move(value.host), value.port}
{
}
/**
* \brief Constructs an address containing a UNIX socket path.
* \details Results in an address with `this->type() == address_type::unix_path`,
* `this->unix_socket_path() == value.path()`.
*
* \par Object lifetimes
* `*this` and `value` will have independent lifetimes (regular value semantics).
*
* \par Exception safety
* No-throw guarantee.
*/
any_address(unix_path value) noexcept : impl_{address_type::unix_path, std::move(value.path), 0} {}
/**
* \brief Retrieves the type of address that this object contains.
* \par Exception safety
* No-throw guarantee.
*/
address_type type() const noexcept { return impl_.type; }
/**
* \brief Retrieves the hostname that this object contains.
* \par Preconditions
* `this->type() == address_type::host_and_port`
*
* \par Object lifetimes
* The returned view points into `*this`, and is valid as long as `*this`
* is alive and hasn't been assigned to or moved from.
*
* \par Exception safety
* No-throw guarantee.
*/
string_view hostname() const noexcept
{
BOOST_ASSERT(type() == address_type::host_and_port);
return impl_.address;
}
/**
* \brief Retrieves the port that this object contains.
* \par Preconditions
* `this->type() == address_type::host_and_port`
*
* \par Exception safety
* No-throw guarantee.
*/
unsigned short port() const noexcept
{
BOOST_ASSERT(type() == address_type::host_and_port);
return impl_.port;
}
/**
* \brief Retrieves the UNIX socket path that this object contains.
* \par Preconditions
* `this->type() == address_type::unix_path`
*
* \par Object lifetimes
* The returned view points into `*this`, and is valid as long as `*this`
* is alive and hasn't been assigned to or moved from.
*
* \par Exception safety
* No-throw guarantee.
*/
string_view unix_socket_path() const noexcept
{
BOOST_ASSERT(type() == address_type::unix_path);
return impl_.address;
}
/**
* \brief Replaces the current object with a host and port.
* \details
* Destroys the current contained object and constructs a new
* host and port from the passed components. This function can
* change the underlying type of object held by `*this`.
* \n
* The constructed object has `this->type() == address_type::host_and_port`,
* `this->hostname() == hostname` and `this->port() == port`.
* \n
* An empty hostname is equivalent to `localhost`.
* \n
* \par Exception safety
* Basic guarantee. Memory allocations may throw.
* \par Object lifetimes
* Invalidates views pointing into `*this`.
*/
void emplace_host_and_port(std::string hostname, unsigned short port = default_port)
{
impl_.type = address_type::host_and_port;
impl_.address = std::move(hostname);
impl_.port = port;
}
/**
* \brief Replaces the current object with a UNIX socket path.
* \details
* Destroys the current contained object and constructs a new
* UNIX socket path from the passed value. This function can
* change the underlying type of object held by `*this`.
* \n
* The constructed object has `this->type() == address_type::unix_path` and
* `this->unix_socket_path() == path`.
* \n
* \par Exception safety
* Basic guarantee. Memory allocations may throw.
* \par Object lifetimes
* Invalidates views pointing into `*this`.
*/
void emplace_unix_path(std::string path)
{
impl_.type = address_type::unix_path;
impl_.address = std::move(path);
impl_.port = 0;
}
/**
* \brief Tests for equality.
* \details Two addresses are equal if they have the same type and individual components.
* \par Exception safety
* No-throw guarantee.
*/
bool operator==(const any_address& rhs) const noexcept
{
return impl_.type == rhs.impl_.type && impl_.address == rhs.impl_.address &&
impl_.port == rhs.impl_.port;
}
/**
* \brief Tests for inequality.
* \par Exception safety
* No-throw guarantee.
*/
bool operator!=(const any_address& rhs) const noexcept { return !(*this == rhs); }
};
} // namespace mysql
} // namespace boost
#endif