Compare commits

..

2 Commits

Author SHA1 Message Date
Rafael Kitover
fd7003a35f build: lower Intel macOS req to 10.10 from 10.15
Convert the C++17 code in the bundled SFML code to C++14 to allow for
targeting macOS 10.10 (Yosemite) instead of 10.15 (Catalina.)

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-04-30 18:17:17 +00:00
Rafael Kitover
4cf6cccbaf build: bundle SFML 3.x sys/network in third_party
Remove the SFML external dependency, include the SFML 3.0.1 system and
network libraries in third_party and adjust the build code, tools and
documentation accordingly.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-04-24 16:34:42 +00:00
68 changed files with 6889 additions and 513 deletions

View File

@@ -182,8 +182,18 @@ endif()
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
if(NOT TRANSLATIONS_ONLY) if(NOT TRANSLATIONS_ONLY)
add_subdirectory(third_party/include/nonstd) include_directories(third_party/include/nonstd)
include_directories(third_party/include/ghc)
add_subdirectory(third_party/include/stb) add_subdirectory(third_party/include/stb)
if(ENABLE_LINK)
include_directories(third_party/sfml/include)
add_subdirectory(third_party/sfml/src/SFML/System EXCLUDE_FROM_ALL)
add_subdirectory(third_party/sfml/src/SFML/Network EXCLUDE_FROM_ALL)
set(SFML_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/sfml/include)
set(SFML_LIBRARIES sfml-system sfml-network)
endif()
add_subdirectory(src/core) add_subdirectory(src/core)
add_subdirectory(src/components) add_subdirectory(src/components)
add_subdirectory(src/sdl) add_subdirectory(src/sdl)

View File

@@ -119,10 +119,3 @@ if(ENABLE_LINK OR ENABLE_WX)
message(FATAL_ERROR "NLS requires libintl/gettext") message(FATAL_ERROR "NLS requires libintl/gettext")
endif() endif()
endif() endif()
if(ENABLE_LINK)
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/sfml/src/SFML/System EXCLUDE_FROM_ALL)
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/sfml/src/SFML/Network EXCLUDE_FROM_ALL)
set(SFML_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/sfml/include)
set(SFML_LIBRARIES sfml-system sfml-network)
endif()

View File

@@ -68,6 +68,8 @@ if(CMAKE_VERSION VERSION_LESS "3.25")
endif() endif()
endif() endif()
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++14>)
set(CMAKE_RC_FLAGS "-c65001 /DWIN32" CACHE STRING "" FORCE) set(CMAKE_RC_FLAGS "-c65001 /DWIN32" CACHE STRING "" FORCE)
# We need to explicitly set all of these to override the CMake defaults. # We need to explicitly set all of these to override the CMake defaults.

6075
third_party/include/ghc/filesystem.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

38
third_party/include/ghc/fs_fwd.hpp vendored Normal file
View File

@@ -0,0 +1,38 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
// fs_fwd.hpp - The forwarding header for the header/implementation separated usage of
// ghc::filesystem.
// This file can be include at any place, where ghc::filesystem api is needed while
// not bleeding implementation details (e.g. system includes) into the global namespace,
// as long as one cpp includes fs_impl.hpp to deliver the matching implementations.
//---------------------------------------------------------------------------------------
#ifndef GHC_FILESYSTEM_FWD_H
#define GHC_FILESYSTEM_FWD_H
#define GHC_FILESYSTEM_FWD
#include "filesystem.hpp"
#endif // GHC_FILESYSTEM_FWD_H

35
third_party/include/ghc/fs_impl.hpp vendored Normal file
View File

@@ -0,0 +1,35 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
// fs_impl.hpp - The implementation header for the header/implementation separated usage of
// ghc::filesystem.
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
// The cpp has to include this before including fs_fwd.hpp directly or via a different
// header to work.
//---------------------------------------------------------------------------------------
#define GHC_FILESYSTEM_IMPLEMENTATION
#include "filesystem.hpp"

77
third_party/include/ghc/fs_std.hpp vendored Normal file
View File

@@ -0,0 +1,77 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
// fs_std.hpp - The dynamic switching header that includes std::filesystem if detected
// or ghc::filesystem if not, and makes the resulting API available in the
// namespace fs.
//---------------------------------------------------------------------------------------
#ifndef GHC_FILESYSTEM_STD_H
#define GHC_FILESYSTEM_STD_H
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
#define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif
#ifdef GHC_USE_STD_FS
#include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
#else
#include "filesystem.hpp"
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif
#endif // GHC_FILESYSTEM_STD_H

79
third_party/include/ghc/fs_std_fwd.hpp vendored Normal file
View File

@@ -0,0 +1,79 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
// fs_std_fwd.hpp - The forwarding header for the header/implementation separated usage of
// ghc::filesystem that uses std::filesystem if it detects it.
// This file can be include at any place, where fs::filesystem api is needed while
// not bleeding implementation details (e.g. system includes) into the global namespace,
// as long as one cpp includes fs_std_impl.hpp to deliver the matching implementations.
//---------------------------------------------------------------------------------------
#ifndef GHC_FILESYSTEM_STD_FWD_H
#define GHC_FILESYSTEM_STD_FWD_H
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
#define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif
#ifdef GHC_USE_STD_FS
#include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
#else
#include "fs_fwd.hpp"
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif
#endif // GHC_FILESYSTEM_STD_FWD_H

60
third_party/include/ghc/fs_std_impl.hpp vendored Normal file
View File

@@ -0,0 +1,60 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
// fs_std_impl.hpp - The implementation header for the header/implementation separated usage of
// ghc::filesystem that does nothing if std::filesystem is detected.
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
// header to work.
//---------------------------------------------------------------------------------------
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
#define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif
#ifndef GHC_USE_STD_FS
#include "fs_impl.hpp"
#endif

View File

@@ -114,9 +114,9 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Ensure minimum C++ language standard version is met // Ensure minimum C++ language standard version is met
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#if (defined(_MSVC_LANG) && _MSVC_LANG < 201703L) || (!defined(_MSVC_LANG) && __cplusplus < 201703L) //#if (defined(_MSVC_LANG) && _MSVC_LANG < 201703L) || (!defined(_MSVC_LANG) && __cplusplus < 201703L)
#error "Enable C++17 or newer for your compiler (e.g. -std=c++17 for GCC/Clang or /std:c++17 for MSVC)" //#error "Enable C++17 or newer for your compiler (e.g. -std=c++17 for GCC/Clang or /std:c++17 for MSVC)"
#endif //#endif
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -33,7 +33,7 @@
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include <filesystem> #include "filesystem.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -201,13 +201,13 @@ public:
/// \return Directory name /// \return Directory name
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] const std::filesystem::path& getDirectory() const; [[nodiscard]] const ghc::filesystem::path& getDirectory() const;
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::filesystem::path m_directory; //!< Directory extracted from the response message ghc::filesystem::path m_directory; //!< Directory extracted from the response message
}; };
@@ -438,7 +438,7 @@ public:
/// \see `deleteFile` /// \see `deleteFile`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Response renameFile(const std::filesystem::path& file, const std::filesystem::path& newName); [[nodiscard]] Response renameFile(const ghc::filesystem::path& file, const ghc::filesystem::path& newName);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Remove an existing file /// \brief Remove an existing file
@@ -455,7 +455,7 @@ public:
/// \see `renameFile` /// \see `renameFile`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Response deleteFile(const std::filesystem::path& name); [[nodiscard]] Response deleteFile(const ghc::filesystem::path& name);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Download a file from the server /// \brief Download a file from the server
@@ -477,8 +477,8 @@ public:
/// \see `upload` /// \see `upload`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Response download(const std::filesystem::path& remoteFile, [[nodiscard]] Response download(const ghc::filesystem::path& remoteFile,
const std::filesystem::path& localPath, const ghc::filesystem::path& localPath,
TransferMode mode = TransferMode::Binary); TransferMode mode = TransferMode::Binary);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -502,8 +502,8 @@ public:
/// \see `download` /// \see `download`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Response upload(const std::filesystem::path& localFile, [[nodiscard]] Response upload(const ghc::filesystem::path& localFile,
const std::filesystem::path& remotePath, const ghc::filesystem::path& remotePath,
TransferMode mode = TransferMode::Binary, TransferMode mode = TransferMode::Binary,
bool append = false); bool append = false);
@@ -511,7 +511,7 @@ public:
/// \brief Send a command to the FTP server /// \brief Send a command to the FTP server
/// ///
/// While the most often used commands are provided as member /// While the most often used commands are provided as member
/// functions in the `sf::Ftp` class, this method can be used /// functions in the `Ftp` class, this method can be used
/// to send any FTP command to the server. If the command /// to send any FTP command to the server. If the command
/// requires one or more parameters, they can be specified /// requires one or more parameters, they can be specified
/// in `parameter`. If the server returns information, you /// in `parameter`. If the server returns information, you
@@ -557,10 +557,10 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Ftp /// \class Ftp
/// \ingroup network /// \ingroup network
/// ///
/// `sf::Ftp` is a very simple FTP client that allows you /// `Ftp` is a very simple FTP client that allows you
/// to communicate with a FTP server. The FTP protocol allows /// to communicate with a FTP server. The FTP protocol allows
/// you to manipulate a remote file system (list files, /// you to manipulate a remote file system (list files,
/// upload, download, create, remove, ...). /// upload, download, create, remove, ...).
@@ -575,7 +575,7 @@ private:
/// status code as well as a message from the server. Some /// status code as well as a message from the server. Some
/// commands such as `getWorkingDirectory()` and `getDirectoryListing()` /// commands such as `getWorkingDirectory()` and `getDirectoryListing()`
/// return additional data, and use a class derived from /// return additional data, and use a class derived from
/// `sf::Ftp::Response` to provide this data. The most often used /// `Ftp::Response` to provide this data. The most often used
/// commands are directly provided as member functions, but it is /// commands are directly provided as member functions, but it is
/// also possible to use specific commands with the `sendCommand()` function. /// also possible to use specific commands with the `sendCommand()` function.
/// ///
@@ -590,10 +590,10 @@ private:
/// Usage example: /// Usage example:
/// \code /// \code
/// // Create a new FTP client /// // Create a new FTP client
/// sf::Ftp ftp; /// Ftp ftp;
/// ///
/// // Connect to the server /// // Connect to the server
/// sf::Ftp::Response response = ftp.connect("ftp://ftp.myserver.com"); /// Ftp::Response response = ftp.connect("ftp://ftp.myserver.com");
/// if (response.isOk()) /// if (response.isOk())
/// std::cout << "Connected" << std::endl; /// std::cout << "Connected" << std::endl;
/// ///
@@ -603,7 +603,7 @@ private:
/// std::cout << "Logged in" << std::endl; /// std::cout << "Logged in" << std::endl;
/// ///
/// // Print the working directory /// // Print the working directory
/// sf::Ftp::DirectoryResponse directory = ftp.getWorkingDirectory(); /// Ftp::DirectoryResponse directory = ftp.getWorkingDirectory();
/// if (directory.isOk()) /// if (directory.isOk())
/// std::cout << "Working directory: " << directory.getDirectory() << std::endl; /// std::cout << "Working directory: " << directory.getDirectory() << std::endl;
/// ///
@@ -613,7 +613,7 @@ private:
/// std::cout << "Created new directory" << std::endl; /// std::cout << "Created new directory" << std::endl;
/// ///
/// // Upload a file to this new directory /// // Upload a file to this new directory
/// response = ftp.upload("local-path/file.txt", "files", sf::Ftp::TransferMode::Ascii); /// response = ftp.upload("local-path/file.txt", "files", Ftp::TransferMode::Ascii);
/// if (response.isOk()) /// if (response.isOk())
/// std::cout << "File uploaded" << std::endl; /// std::cout << "File uploaded" << std::endl;
/// ///

View File

@@ -36,7 +36,7 @@
#include <iosfwd> #include <iosfwd>
#include <map> #include <map>
#include <optional> #include <optional.hpp>
#include <string> #include <string>
@@ -411,7 +411,7 @@ private:
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
TcpSocket m_connection; //!< Connection to the host TcpSocket m_connection; //!< Connection to the host
std::optional<IpAddress> m_host; //!< Web host address nonstd::optional<IpAddress> m_host; //!< Web host address
std::string m_hostName; //!< Web host name std::string m_hostName; //!< Web host name
unsigned short m_port{}; //!< Port used for connection with host unsigned short m_port{}; //!< Port used for connection with host
}; };
@@ -420,54 +420,54 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Http /// \class Http
/// \ingroup network /// \ingroup network
/// ///
/// `sf::Http` is a very simple HTTP client that allows you /// `Http` is a very simple HTTP client that allows you
/// to communicate with a web server. You can retrieve /// to communicate with a web server. You can retrieve
/// web pages, send data to an interactive resource, /// web pages, send data to an interactive resource,
/// download a remote file, etc. The HTTPS protocol is /// download a remote file, etc. The HTTPS protocol is
/// not supported. /// not supported.
/// ///
/// The HTTP client is split into 3 classes: /// The HTTP client is split into 3 classes:
/// \li `sf::Http::Request` /// \li `Http::Request`
/// \li `sf::Http::Response` /// \li `Http::Response`
/// \li `sf::Http` /// \li `Http`
/// ///
/// `sf::Http::Request` builds the request that will be /// `Http::Request` builds the request that will be
/// sent to the server. A request is made of: /// sent to the server. A request is made of:
/// \li a method (what you want to do) /// \li a method (what you want to do)
/// \li a target URI (usually the name of the web page or file) /// \li a target URI (usually the name of the web page or file)
/// \li one or more header fields (options that you can pass to the server) /// \li one or more header fields (options that you can pass to the server)
/// \li an optional body (for POST requests) /// \li an optional body (for POST requests)
/// ///
/// `sf::Http::Response` parse the response from the web server /// `Http::Response` parse the response from the web server
/// and provides getters to read them. The response contains: /// and provides getters to read them. The response contains:
/// \li a status code /// \li a status code
/// \li header fields (that may be answers to the ones that you requested) /// \li header fields (that may be answers to the ones that you requested)
/// \li a body, which contains the contents of the requested resource /// \li a body, which contains the contents of the requested resource
/// ///
/// `sf::Http` provides a simple function, SendRequest, to send a /// `Http` provides a simple function, SendRequest, to send a
/// `sf::Http::Request` and return the corresponding `sf::Http::Response` /// `Http::Request` and return the corresponding `Http::Response`
/// from the server. /// from the server.
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// // Create a new HTTP client /// // Create a new HTTP client
/// sf::Http http; /// Http http;
/// ///
/// // We'll work on http://www.sfml-dev.org /// // We'll work on http://www.sfml-dev.org
/// http.setHost("http://www.sfml-dev.org"); /// http.setHost("http://www.sfml-dev.org");
/// ///
/// // Prepare a request to get the 'features.php' page /// // Prepare a request to get the 'features.php' page
/// sf::Http::Request request("features.php"); /// Http::Request request("features.php");
/// ///
/// // Send the request /// // Send the request
/// sf::Http::Response response = http.sendRequest(request); /// Http::Response response = http.sendRequest(request);
/// ///
/// // Check the status code and display the result /// // Check the status code and display the result
/// sf::Http::Response::Status status = response.getStatus(); /// Http::Response::Status status = response.getStatus();
/// if (status == sf::Http::Response::Status::Ok) /// if (status == Http::Response::Status::Ok)
/// { /// {
/// std::cout << response.getBody() << std::endl; /// std::cout << response.getBody() << std::endl;
/// } /// }

View File

@@ -32,9 +32,8 @@
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include <iosfwd> #include <iosfwd>
#include <optional> #include <optional.hpp>
#include <string> #include <string>
#include <string_view>
#include <cstdint> #include <cstdint>
@@ -56,10 +55,10 @@ public:
/// ///
/// \param address IP address or network name /// \param address IP address or network name
/// ///
/// \return Address if provided argument was valid, otherwise `std::nullopt` /// \return Address if provided argument was valid, otherwise `nonstd::nullopt`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] static std::optional<IpAddress> resolve(std::string_view address); [[nodiscard]] static nonstd::optional<IpAddress> resolve(std::string address);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Construct the address from 4 bytes /// \brief Construct the address from 4 bytes
@@ -112,7 +111,7 @@ public:
/// address, and should be used for optimization purposes only /// address, and should be used for optimization purposes only
/// (like sending the address through a socket). /// (like sending the address through a socket).
/// The integer produced by this function can then be converted /// The integer produced by this function can then be converted
/// back to a `sf::IpAddress` with the proper constructor. /// back to a `IpAddress` with the proper constructor.
/// ///
/// \return 32-bits unsigned integer representation of the address /// \return 32-bits unsigned integer representation of the address
/// ///
@@ -130,12 +129,12 @@ public:
/// Unlike getPublicAddress, this function is fast and may be /// Unlike getPublicAddress, this function is fast and may be
/// used safely anywhere. /// used safely anywhere.
/// ///
/// \return Local IP address of the computer on success, `std::nullopt` otherwise /// \return Local IP address of the computer on success, `nonstd::nullopt` otherwise
/// ///
/// \see `getPublicAddress` /// \see `getPublicAddress`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] static std::optional<IpAddress> getLocalAddress(); [[nodiscard]] static nonstd::optional<IpAddress> getLocalAddress();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the computer's public address /// \brief Get the computer's public address
@@ -154,12 +153,12 @@ public:
/// ///
/// \param timeout Maximum time to wait /// \param timeout Maximum time to wait
/// ///
/// \return Public IP address of the computer on success, `std::nullopt` otherwise /// \return Public IP address of the computer on success, `nonstd::nullopt` otherwise
/// ///
/// \see `getLocalAddress` /// \see `getLocalAddress`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] static std::optional<IpAddress> getPublicAddress(Time timeout = Time::Zero); [[nodiscard]] static nonstd::optional<IpAddress> getPublicAddress(Time timeout = Time::Zero);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Static member data // Static member data
@@ -254,7 +253,7 @@ private:
/// \return Reference to the input stream /// \return Reference to the input stream
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
SFML_NETWORK_API std::istream& operator>>(std::istream& stream, std::optional<IpAddress>& address); SFML_NETWORK_API std::istream& operator>>(std::istream& stream, nonstd::optional<IpAddress>& address);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Overload of `operator<<` to print an IP address to an output stream /// \brief Overload of `operator<<` to print an IP address to an output stream
@@ -271,27 +270,27 @@ SFML_NETWORK_API std::ostream& operator<<(std::ostream& stream, IpAddress addres
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::IpAddress /// \class IpAddress
/// \ingroup network /// \ingroup network
/// ///
/// `sf::IpAddress` is a utility class for manipulating network /// `IpAddress` is a utility class for manipulating network
/// addresses. It provides a set a implicit constructors and /// addresses. It provides a set a implicit constructors and
/// conversion functions to easily build or transform an IP /// conversion functions to easily build or transform an IP
/// address from/to various representations. /// address from/to various representations.
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// auto a2 = sf::IpAddress::resolve("127.0.0.1"); // the local host address /// auto a2 = IpAddress::resolve("127.0.0.1"); // the local host address
/// auto a3 = sf::IpAddress::Broadcast; // the broadcast address /// auto a3 = IpAddress::Broadcast; // the broadcast address
/// sf::IpAddress a4(192, 168, 1, 56); // a local address /// IpAddress a4(192, 168, 1, 56); // a local address
/// auto a5 = sf::IpAddress::resolve("my_computer"); // a local address created from a network name /// auto a5 = IpAddress::resolve("my_computer"); // a local address created from a network name
/// auto a6 = sf::IpAddress::resolve("89.54.1.169"); // a distant address /// auto a6 = IpAddress::resolve("89.54.1.169"); // a distant address
/// auto a7 = sf::IpAddress::resolve("www.google.com"); // a distant address created from a network name /// auto a7 = IpAddress::resolve("www.google.com"); // a distant address created from a network name
/// auto a8 = sf::IpAddress::getLocalAddress(); // my address on the local network /// auto a8 = IpAddress::getLocalAddress(); // my address on the local network
/// auto a9 = sf::IpAddress::getPublicAddress(); // my address on the internet /// auto a9 = IpAddress::getPublicAddress(); // my address on the internet
/// \endcode /// \endcode
/// ///
/// Note that `sf::IpAddress` currently doesn't support IPv6 /// Note that `IpAddress` currently doesn't support IPv6
/// nor other types of network addresses. /// nor other types of network addresses.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -423,7 +423,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::vector<std::byte> m_data; //!< Data stored in the packet std::vector<unsigned char> m_data; //!< Data stored in the packet
std::size_t m_readPos{}; //!< Current reading position in the packet std::size_t m_readPos{}; //!< Current reading position in the packet
std::size_t m_sendPos{}; //!< Current send position in the packet (for handling partial sends) std::size_t m_sendPos{}; //!< Current send position in the packet (for handling partial sends)
bool m_isValid{true}; //!< Reading state of the packet bool m_isValid{true}; //!< Reading state of the packet
@@ -433,19 +433,19 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Packet /// \class Packet
/// \ingroup network /// \ingroup network
/// ///
/// Packets provide a safe and easy way to serialize data, /// Packets provide a safe and easy way to serialize data,
/// in order to send it over the network using sockets /// in order to send it over the network using sockets
/// (`sf::TcpSocket`, `sf::UdpSocket`). /// (`TcpSocket`, `UdpSocket`).
/// ///
/// Packets solve 2 fundamental problems that arise when /// Packets solve 2 fundamental problems that arise when
/// transferring data over the network: /// transferring data over the network:
/// \li data is interpreted correctly according to the endianness /// \li data is interpreted correctly according to the endianness
/// \li the bounds of the packet are preserved (one send == one receive) /// \li the bounds of the packet are preserved (one send == one receive)
/// ///
/// The `sf::Packet` class provides both input and output modes. /// The `Packet` class provides both input and output modes.
/// It is designed to follow the behavior of standard C++ streams, /// It is designed to follow the behavior of standard C++ streams,
/// using operators >> and << to extract and insert data. /// using operators >> and << to extract and insert data.
/// ///
@@ -461,16 +461,16 @@ private:
/// double d = 5.89; /// double d = 5.89;
/// ///
/// // Group the variables to send into a packet /// // Group the variables to send into a packet
/// sf::Packet packet; /// Packet packet;
/// packet << x << s << d; /// packet << x << s << d;
/// ///
/// // Send it over the network (socket is a valid sf::TcpSocket) /// // Send it over the network (socket is a valid TcpSocket)
/// socket.send(packet); /// socket.send(packet);
/// ///
/// ----------------------------------------------------------------- /// -----------------------------------------------------------------
/// ///
/// // Receive the packet at the other end /// // Receive the packet at the other end
/// sf::Packet packet; /// Packet packet;
/// socket.receive(packet); /// socket.receive(packet);
/// ///
/// // Extract the variables contained in the packet /// // Extract the variables contained in the packet
@@ -488,7 +488,7 @@ private:
/// \li `bool` /// \li `bool`
/// \li fixed-size integer types (`int[8|16|32]_t`, `uint[8|16|32]_t`) /// \li fixed-size integer types (`int[8|16|32]_t`, `uint[8|16|32]_t`)
/// \li floating point numbers (`float`, `double`) /// \li floating point numbers (`float`, `double`)
/// \li string types (`char*`, `wchar_t*`, `std::string`, `std::wstring`, `sf::String`) /// \li string types (`char*`, `wchar_t*`, `std::string`, `std::wstring`, `String`)
/// ///
/// Like standard streams, it is also possible to define your own /// Like standard streams, it is also possible to define your own
/// overloads of operators >> and << in order to handle your /// overloads of operators >> and << in order to handle your
@@ -502,12 +502,12 @@ private:
/// std::string str; /// std::string str;
/// }; /// };
/// ///
/// sf::Packet& operator <<(sf::Packet& packet, const MyStruct& m) /// Packet& operator <<(Packet& packet, const MyStruct& m)
/// { /// {
/// return packet << m.number << m.integer << m.str; /// return packet << m.number << m.integer << m.str;
/// } /// }
/// ///
/// sf::Packet& operator >>(sf::Packet& packet, MyStruct& m) /// Packet& operator >>(Packet& packet, MyStruct& m)
/// { /// {
/// return packet >> m.number >> m.integer >> m.str; /// return packet >> m.number >> m.integer >> m.str;
/// } /// }
@@ -517,12 +517,12 @@ private:
/// custom transformations to the data before it is sent, /// custom transformations to the data before it is sent,
/// and after it is received. This is typically used to /// and after it is received. This is typically used to
/// handle automatic compression or encryption of the data. /// handle automatic compression or encryption of the data.
/// This is achieved by inheriting from `sf::Packet`, and overriding /// This is achieved by inheriting from `Packet`, and overriding
/// the onSend and onReceive functions. /// the onSend and onReceive functions.
/// ///
/// Here is an example: /// Here is an example:
/// \code /// \code
/// class ZipPacket : public sf::Packet /// class ZipPacket : public Packet
/// { /// {
/// const void* onSend(std::size_t& size) override /// const void* onSend(std::size_t& size) override
/// { /// {
@@ -547,6 +547,6 @@ private:
/// ... /// ...
/// \endcode /// \endcode
/// ///
/// \see `sf::TcpSocket`, `sf::UdpSocket` /// \see `TcpSocket`, `UdpSocket`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -195,7 +195,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Socket /// \class Socket
/// \ingroup network /// \ingroup network
/// ///
/// This class mainly defines internal stuff to be used by /// This class mainly defines internal stuff to be used by
@@ -224,6 +224,6 @@ private:
/// the socket often enough, and cannot afford blocking /// the socket often enough, and cannot afford blocking
/// this loop. /// this loop.
/// ///
/// \see `sf::TcpListener`, `sf::TcpSocket`, `sf::UdpSocket` /// \see `TcpListener`, `TcpSocket`, `UdpSocket`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -177,7 +177,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::SocketSelector /// \class SocketSelector
/// \ingroup network /// \ingroup network
/// ///
/// Socket selectors provide a way to wait until some data is /// Socket selectors provide a way to wait until some data is
@@ -189,9 +189,9 @@ private:
/// all the sockets. /// all the sockets.
/// ///
/// All types of sockets can be used in a selector: /// All types of sockets can be used in a selector:
/// \li `sf::TcpListener` /// \li `TcpListener`
/// \li `sf::TcpSocket` /// \li `TcpSocket`
/// \li `sf::UdpSocket` /// \li `UdpSocket`
/// ///
/// A selector doesn't store its own copies of the sockets /// A selector doesn't store its own copies of the sockets
/// (socket classes are not copyable anyway), it simply keeps /// (socket classes are not copyable anyway), it simply keeps
@@ -208,17 +208,17 @@ private:
/// Usage example: /// Usage example:
/// \code /// \code
/// // Create a socket to listen to new connections /// // Create a socket to listen to new connections
/// sf::TcpListener listener; /// TcpListener listener;
/// if (listener.listen(55001) != sf::Socket::Status::Done) /// if (listener.listen(55001) != Socket::Status::Done)
/// { /// {
/// // Handle error... /// // Handle error...
/// } /// }
/// ///
/// // Create a list to store the future clients /// // Create a list to store the future clients
/// std::vector<sf::TcpSocket> clients; /// std::vector<TcpSocket> clients;
/// ///
/// // Create a selector /// // Create a selector
/// sf::SocketSelector selector; /// SocketSelector selector;
/// ///
/// // Add the listener to the selector /// // Add the listener to the selector
/// selector.add(listener); /// selector.add(listener);
@@ -233,8 +233,8 @@ private:
/// if (selector.isReady(listener)) /// if (selector.isReady(listener))
/// { /// {
/// // The listener is ready: there is a pending connection /// // The listener is ready: there is a pending connection
/// sf::TcpSocket client; /// TcpSocket client;
/// if (listener.accept(client) == sf::Socket::Status::Done) /// if (listener.accept(client) == Socket::Status::Done)
/// { /// {
/// // Add the new client to the selector so that we will /// // Add the new client to the selector so that we will
/// // be notified when they send something /// // be notified when they send something
@@ -251,13 +251,13 @@ private:
/// else /// else
/// { /// {
/// // The listener socket is not ready, test all other sockets (the clients) /// // The listener socket is not ready, test all other sockets (the clients)
/// for (sf::TcpSocket& client : clients) /// for (TcpSocket& client : clients)
/// { /// {
/// if (selector.isReady(client)) /// if (selector.isReady(client))
/// { /// {
/// // The client has sent some data, we can receive it /// // The client has sent some data, we can receive it
/// sf::Packet packet; /// Packet packet;
/// if (client.receive(packet) == sf::Socket::Status::Done) /// if (client.receive(packet) == Socket::Status::Done)
/// { /// {
/// ... /// ...
/// } /// }
@@ -268,6 +268,6 @@ private:
/// } /// }
/// \endcode /// \endcode
/// ///
/// \see `sf::Socket` /// \see `Socket`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -73,7 +73,7 @@ public:
/// function is called, it will stop listening on the old /// function is called, it will stop listening on the old
/// port before starting to listen on the new port. /// port before starting to listen on the new port.
/// ///
/// When providing `sf::Socket::AnyPort` as port, the listener /// When providing `Socket::AnyPort` as port, the listener
/// will request an available port from the system. /// will request an available port from the system.
/// The chosen port can be retrieved by calling `getLocalPort()`. /// The chosen port can be retrieved by calling `getLocalPort()`.
/// ///
@@ -119,7 +119,7 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::TcpListener /// \class TcpListener
/// \ingroup network /// \ingroup network
/// ///
/// A listener socket is a special type of socket that listens to /// A listener socket is a special type of socket that listens to
@@ -127,14 +127,14 @@ public:
/// This is all it can do. /// This is all it can do.
/// ///
/// When a new connection is received, you must call accept and /// When a new connection is received, you must call accept and
/// the listener returns a new instance of `sf::TcpSocket` that /// the listener returns a new instance of `TcpSocket` that
/// is properly initialized and can be used to communicate with /// is properly initialized and can be used to communicate with
/// the new client. /// the new client.
/// ///
/// Listener sockets are specific to the TCP protocol, /// Listener sockets are specific to the TCP protocol,
/// UDP sockets are connectionless and can therefore communicate /// UDP sockets are connectionless and can therefore communicate
/// directly. As a consequence, a listener socket will always /// directly. As a consequence, a listener socket will always
/// return the new connections as `sf::TcpSocket` instances. /// return the new connections as `TcpSocket` instances.
/// ///
/// A listener is automatically closed on destruction, like all /// A listener is automatically closed on destruction, like all
/// other types of socket. However if you want to stop listening /// other types of socket. However if you want to stop listening
@@ -145,14 +145,14 @@ public:
/// \code /// \code
/// // Create a listener socket and make it wait for new /// // Create a listener socket and make it wait for new
/// // connections on port 55001 /// // connections on port 55001
/// sf::TcpListener listener; /// TcpListener listener;
/// listener.listen(55001); /// listener.listen(55001);
/// ///
/// // Endless loop that waits for new connections /// // Endless loop that waits for new connections
/// while (running) /// while (running)
/// { /// {
/// sf::TcpSocket client; /// TcpSocket client;
/// if (listener.accept(client) == sf::Socket::Done) /// if (listener.accept(client) == Socket::Done)
/// { /// {
/// // A new client just connected! /// // A new client just connected!
/// std::cout << "New connection received from " << client.getRemoteAddress().value() << std::endl; /// std::cout << "New connection received from " << client.getRemoteAddress().value() << std::endl;
@@ -161,6 +161,6 @@ public:
/// } /// }
/// \endcode /// \endcode
/// ///
/// \see `sf::TcpSocket`, `sf::Socket` /// \see `TcpSocket`, `Socket`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -33,7 +33,7 @@
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include <optional> #include <optional.hpp>
#include <vector> #include <vector>
#include <cstddef> #include <cstddef>
@@ -82,7 +82,7 @@ public:
/// \see `getRemotePort` /// \see `getRemotePort`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<IpAddress> getRemoteAddress() const; [[nodiscard]] nonstd::optional<IpAddress> getRemoteAddress() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the port of the connected peer to which /// \brief Get the port of the connected peer to which
@@ -183,7 +183,7 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Send a formatted packet of data to the remote peer /// \brief Send a formatted packet of data to the remote peer
/// ///
/// In non-blocking mode, if this function returns `sf::Socket::Status::Partial`, /// In non-blocking mode, if this function returns `Socket::Status::Partial`,
/// you \em must retry sending the same unmodified packet before sending /// you \em must retry sending the same unmodified packet before sending
/// anything else in order to guarantee the packet arrives at the remote /// anything else in order to guarantee the packet arrives at the remote
/// peer uncorrupted. /// peer uncorrupted.
@@ -225,21 +225,21 @@ private:
{ {
std::uint32_t size{}; //!< Data of packet size std::uint32_t size{}; //!< Data of packet size
std::size_t sizeReceived{}; //!< Number of size bytes received so far std::size_t sizeReceived{}; //!< Number of size bytes received so far
std::vector<std::byte> data; //!< Data of the packet std::vector<unsigned char> data; //!< Data of the packet
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
PendingPacket m_pendingPacket; //!< Temporary data of the packet currently being received PendingPacket m_pendingPacket; //!< Temporary data of the packet currently being received
std::vector<std::byte> m_blockToSendBuffer; //!< Buffer used to prepare data being sent from the socket std::vector<unsigned char> m_blockToSendBuffer; //!< Buffer used to prepare data being sent from the socket
}; };
} // namespace sf } // namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::TcpSocket /// \class TcpSocket
/// \ingroup network /// \ingroup network
/// ///
/// TCP is a connected protocol, which means that a TCP /// TCP is a connected protocol, which means that a TCP
@@ -263,9 +263,9 @@ private:
/// one call to Send will exactly match one call to Receive /// one call to Send will exactly match one call to Receive
/// at the other end of the socket. /// at the other end of the socket.
/// ///
/// The high-level interface uses packets (see `sf::Packet`), /// The high-level interface uses packets (see `Packet`),
/// which are easier to use and provide more safety regarding /// which are easier to use and provide more safety regarding
/// the data that is exchanged. You can look at the `sf::Packet` /// the data that is exchanged. You can look at the `Packet`
/// class to get more details about how they work. /// class to get more details about how they work.
/// ///
/// The socket is automatically disconnected when it is destroyed, /// The socket is automatically disconnected when it is destroyed,
@@ -277,7 +277,7 @@ private:
/// // ----- The client ----- /// // ----- The client -----
/// ///
/// // Create a socket and connect it to 192.168.1.50 on port 55001 /// // Create a socket and connect it to 192.168.1.50 on port 55001
/// sf::TcpSocket socket; /// TcpSocket socket;
/// socket.connect("192.168.1.50", 55001); /// socket.connect("192.168.1.50", 55001);
/// ///
/// // Send a message to the connected host /// // Send a message to the connected host
@@ -293,11 +293,11 @@ private:
/// // ----- The server ----- /// // ----- The server -----
/// ///
/// // Create a listener to wait for incoming connections on port 55001 /// // Create a listener to wait for incoming connections on port 55001
/// sf::TcpListener listener; /// TcpListener listener;
/// listener.listen(55001); /// listener.listen(55001);
/// ///
/// // Wait for a connection /// // Wait for a connection
/// sf::TcpSocket socket; /// TcpSocket socket;
/// listener.accept(socket); /// listener.accept(socket);
/// std::cout << "New client connected: " << socket.getRemoteAddress().value() << std::endl; /// std::cout << "New client connected: " << socket.getRemoteAddress().value() << std::endl;
/// ///
@@ -312,6 +312,6 @@ private:
/// socket.send(message.c_str(), message.size() + 1); /// socket.send(message.c_str(), message.size() + 1);
/// \endcode /// \endcode
/// ///
/// \see `sf::Socket`, `sf::UdpSocket`, `sf::Packet` /// \see `Socket`, `UdpSocket`, `Packet`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -32,7 +32,7 @@
#include <SFML/Network/IpAddress.hpp> #include <SFML/Network/IpAddress.hpp>
#include <SFML/Network/Socket.hpp> #include <SFML/Network/Socket.hpp>
#include <optional> #include <optional.hpp>
#include <vector> #include <vector>
#include <cstddef> #include <cstddef>
@@ -80,7 +80,7 @@ public:
/// Binding the socket to a port is necessary for being /// Binding the socket to a port is necessary for being
/// able to receive data on that port. /// able to receive data on that port.
/// ///
/// When providing `sf::Socket::AnyPort` as port, the listener /// When providing `Socket::AnyPort` as port, the listener
/// will request an available port from the system. /// will request an available port from the system.
/// The chosen port can be retrieved by calling `getLocalPort()`. /// The chosen port can be retrieved by calling `getLocalPort()`.
/// ///
@@ -156,7 +156,7 @@ public:
[[nodiscard]] Status receive(void* data, [[nodiscard]] Status receive(void* data,
std::size_t size, std::size_t size,
std::size_t& received, std::size_t& received,
std::optional<IpAddress>& remoteAddress, nonstd::optional<IpAddress>& remoteAddress,
unsigned short& remotePort); unsigned short& remotePort);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -192,20 +192,20 @@ public:
/// \see `send` /// \see `send`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Status receive(Packet& packet, std::optional<IpAddress>& remoteAddress, unsigned short& remotePort); [[nodiscard]] Status receive(Packet& packet, nonstd::optional<IpAddress>& remoteAddress, unsigned short& remotePort);
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::vector<std::byte> m_buffer{MaxDatagramSize}; //!< Temporary buffer holding the received data in Receive(Packet) std::vector<unsigned char> m_buffer; //!< Temporary buffer holding the received data in Receive(Packet)
}; };
} // namespace sf } // namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::UdpSocket /// \class UdpSocket
/// \ingroup network /// \ingroup network
/// ///
/// A UDP socket is a connectionless socket. Instead of /// A UDP socket is a connectionless socket. Instead of
@@ -230,9 +230,9 @@ private:
/// Sending and receiving data can use either the low-level /// Sending and receiving data can use either the low-level
/// or the high-level functions. The low-level functions /// or the high-level functions. The low-level functions
/// process a raw sequence of bytes, whereas the high-level /// process a raw sequence of bytes, whereas the high-level
/// interface uses packets (see `sf::Packet`), which are easier /// interface uses packets (see `Packet`), which are easier
/// to use and provide more safety regarding the data that is /// to use and provide more safety regarding the data that is
/// exchanged. You can look at the `sf::Packet` class to get /// exchanged. You can look at the `Packet` class to get
/// more details about how they work. /// more details about how they work.
/// ///
/// It is important to note that `UdpSocket` is unable to send /// It is important to note that `UdpSocket` is unable to send
@@ -254,33 +254,33 @@ private:
/// // ----- The client ----- /// // ----- The client -----
/// ///
/// // Create a socket and bind it to the port 55001 /// // Create a socket and bind it to the port 55001
/// sf::UdpSocket socket; /// UdpSocket socket;
/// socket.bind(55001); /// socket.bind(55001);
/// ///
/// // Send a message to 192.168.1.50 on port 55002 /// // Send a message to 192.168.1.50 on port 55002
/// std::string message = "Hi, I am " + sf::IpAddress::getLocalAddress().toString(); /// std::string message = "Hi, I am " + IpAddress::getLocalAddress().toString();
/// socket.send(message.c_str(), message.size() + 1, "192.168.1.50", 55002); /// socket.send(message.c_str(), message.size() + 1, "192.168.1.50", 55002);
/// ///
/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else) /// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
/// std::array<char, 1024> buffer; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// std::optional<sf::IpAddress> sender; /// nonstd::optional<IpAddress> sender;
/// unsigned short port; /// unsigned short port;
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done) /// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl; /// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
/// ///
/// // ----- The server ----- /// // ----- The server -----
/// ///
/// // Create a socket and bind it to the port 55002 /// // Create a socket and bind it to the port 55002
/// sf::UdpSocket socket; /// UdpSocket socket;
/// socket.bind(55002); /// socket.bind(55002);
/// ///
/// // Receive a message from anyone /// // Receive a message from anyone
/// std::array<char, 1024> buffer; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// std::optional<sf::IpAddress> sender; /// nonstd::optional<IpAddress> sender;
/// unsigned short port; /// unsigned short port;
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done) /// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl; /// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
/// ///
/// // Send an answer /// // Send an answer
@@ -288,6 +288,6 @@ private:
/// socket.send(message.c_str(), message.size() + 1, sender, port); /// socket.send(message.c_str(), message.size() + 1, sender, port);
/// \endcode /// \endcode
/// ///
/// \see `sf::Socket`, `sf::TcpSocket`, `sf::Packet` /// \see `Socket`, `TcpSocket`, `Packet`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -142,7 +142,7 @@ private:
/// \brief Construct from a number of radians /// \brief Construct from a number of radians
/// ///
/// This function is internal. To construct angle values, /// This function is internal. To construct angle values,
/// use `sf::radians` or `sf::degrees` instead. /// use `radians` or `degrees` instead.
/// ///
/// \param radians Angle in radians /// \param radians Angle in radians
/// ///
@@ -398,8 +398,8 @@ constexpr Angle& operator/=(Angle& left, float right);
/// ///
/// Examples: /// Examples:
/// \code /// \code
/// sf::degrees(90) % sf::degrees(40) // 10 degrees /// degrees(90) % degrees(40) // 10 degrees
/// sf::degrees(-90) % sf::degrees(40) // 30 degrees (not -10) /// degrees(-90) % degrees(40) // 30 degrees (not -10)
/// \endcode /// \endcode
/// ///
/// \param left Left operand (an angle) /// \param left Left operand (an angle)
@@ -426,7 +426,7 @@ namespace Literals
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \relates sf::Angle /// \relates Angle
/// \brief User defined literal for angles in degrees, e.g.\ `10.5_deg` /// \brief User defined literal for angles in degrees, e.g.\ `10.5_deg`
/// ///
/// \param angle Angle in degrees /// \param angle Angle in degrees
@@ -437,7 +437,7 @@ namespace Literals
[[nodiscard]] constexpr Angle operator""_deg(long double angle); [[nodiscard]] constexpr Angle operator""_deg(long double angle);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \relates sf::Angle /// \relates Angle
/// \brief User defined literal for angles in degrees, e.g.\ `90_deg` /// \brief User defined literal for angles in degrees, e.g.\ `90_deg`
/// ///
/// \param angle Angle in degrees /// \param angle Angle in degrees
@@ -448,7 +448,7 @@ namespace Literals
[[nodiscard]] constexpr Angle operator""_deg(unsigned long long int angle); [[nodiscard]] constexpr Angle operator""_deg(unsigned long long int angle);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \relates sf::Angle /// \relates Angle
/// \brief User defined literal for angles in radians, e.g.\ `0.1_rad` /// \brief User defined literal for angles in radians, e.g.\ `0.1_rad`
/// ///
/// \param angle Angle in radians /// \param angle Angle in radians
@@ -459,7 +459,7 @@ namespace Literals
[[nodiscard]] constexpr Angle operator""_rad(long double angle); [[nodiscard]] constexpr Angle operator""_rad(long double angle);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \relates sf::Angle /// \relates Angle
/// \brief User defined literal for angles in radians, e.g.\ `2_rad` /// \brief User defined literal for angles in radians, e.g.\ `2_rad`
/// ///
/// \param angle Angle in radians /// \param angle Angle in radians
@@ -476,10 +476,10 @@ namespace Literals
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Angle /// \class Angle
/// \ingroup system /// \ingroup system
/// ///
/// `sf::Angle` encapsulates an angle value in a flexible way. /// `Angle` encapsulates an angle value in a flexible way.
/// It allows for defining an angle value either as a number /// It allows for defining an angle value either as a number
/// of degrees or radians. It also works the other way /// of degrees or radians. It also works the other way
/// around. You can read an angle value as either a number /// around. You can read an angle value as either a number
@@ -495,17 +495,17 @@ namespace Literals
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// sf::Angle a1 = sf::degrees(90); /// Angle a1 = degrees(90);
/// float radians = a1.asRadians(); // 1.5708f /// float radians = a1.asRadians(); // 1.5708f
/// ///
/// sf::Angle a2 = sf::radians(3.141592654f); /// Angle a2 = radians(3.141592654f);
/// float degrees = a2.asDegrees(); // 180.0f /// float degrees = a2.asDegrees(); // 180.0f
/// ///
/// using namespace sf::Literals; /// using namespace Literals;
/// sf::Angle a3 = 10_deg; // 10 degrees /// Angle a3 = 10_deg; // 10 degrees
/// sf::Angle a4 = 1.5_deg; // 1.5 degrees /// Angle a4 = 1.5_deg; // 1.5 degrees
/// sf::Angle a5 = 1_rad; // 1 radians /// Angle a5 = 1_rad; // 1 radians
/// sf::Angle a6 = 3.14_rad; // 3.14 radians /// Angle a6 = 3.14_rad; // 3.14 radians
/// \endcode /// \endcode
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -32,10 +32,8 @@
namespace sf namespace sf
{ {
namespace priv constexpr float pi = 3.141592654f;
{ constexpr float tau = pi * 2.f;
inline constexpr float pi = 3.141592654f;
inline constexpr float tau = pi * 2.f;
constexpr float positiveRemainder(float a, float b) constexpr float positiveRemainder(float a, float b)
{ {
@@ -43,12 +41,11 @@ constexpr float positiveRemainder(float a, float b)
const float val = a - static_cast<float>(static_cast<int>(a / b)) * b; const float val = a - static_cast<float>(static_cast<int>(a / b)) * b;
return val >= 0.f ? val : val + b; return val >= 0.f ? val : val + b;
} }
} // namespace priv
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr float Angle::asDegrees() const constexpr float Angle::asDegrees() const
{ {
return m_radians * (180.f / priv::pi); return m_radians * (180.f / pi);
} }
@@ -62,14 +59,14 @@ constexpr float Angle::asRadians() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr Angle Angle::wrapSigned() const constexpr Angle Angle::wrapSigned() const
{ {
return radians(priv::positiveRemainder(m_radians + priv::pi, priv::tau) - priv::pi); return radians(positiveRemainder(m_radians + pi, tau) - pi);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr Angle Angle::wrapUnsigned() const constexpr Angle Angle::wrapUnsigned() const
{ {
return radians(priv::positiveRemainder(m_radians, priv::tau)); return radians(positiveRemainder(m_radians, tau));
} }
@@ -82,7 +79,7 @@ constexpr Angle::Angle(float radians) : m_radians(radians)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr Angle degrees(float angle) constexpr Angle degrees(float angle)
{ {
return Angle(angle * (priv::pi / 180.f)); return Angle(angle * (pi / 180.f));
} }
@@ -219,7 +216,7 @@ constexpr float operator/(Angle left, Angle right)
constexpr Angle operator%(Angle left, Angle right) constexpr Angle operator%(Angle left, Angle right)
{ {
assert(right.asRadians() != 0.f && "Angle::operator% cannot modulus by 0"); assert(right.asRadians() != 0.f && "Angle::operator% cannot modulus by 0");
return radians(priv::positiveRemainder(left.asRadians(), right.asRadians())); return radians(positiveRemainder(left.asRadians(), right.asRadians()));
} }
@@ -269,6 +266,6 @@ constexpr Angle operator""_rad(unsigned long long angle)
// Note: the 'inline' keyword here is technically not required, but VS2019 fails // Note: the 'inline' keyword here is technically not required, but VS2019 fails
// to compile with a bogus "multiple definition" error if not explicitly used. // to compile with a bogus "multiple definition" error if not explicitly used.
inline constexpr Angle Angle::Zero; constexpr Angle Angle::Zero;
} // namespace sf } // namespace sf

View File

@@ -40,8 +40,6 @@
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Chooses a monotonic clock of highest resolution /// \brief Chooses a monotonic clock of highest resolution
@@ -50,7 +48,7 @@ namespace priv
/// clocks: `steady_clock` or `system_clock`, whichever has a /// clocks: `steady_clock` or `system_clock`, whichever has a
/// higher precision. /// higher precision.
/// ///
/// `sf::Clock`, however, is aimed towards monotonic time /// `Clock`, however, is aimed towards monotonic time
/// measurements and so `system_clock` could never be a choice /// measurements and so `system_clock` could never be a choice
/// as its subject to discontinuous jumps in the system time /// as its subject to discontinuous jumps in the system time
/// (e.g., if the system administrator manually changes /// (e.g., if the system administrator manually changes
@@ -78,8 +76,6 @@ static_assert(ClockImpl::is_steady, "Provided implementation is not a monotonic
static_assert(std::ratio_less_equal_v<ClockImpl::period, std::micro>, static_assert(std::ratio_less_equal_v<ClockImpl::period, std::micro>,
"Clock resolution is too low. Expecting at least a microsecond precision"); "Clock resolution is too low. Expecting at least a microsecond precision");
} // namespace priv
class Time; class Time;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -157,18 +153,18 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
priv::ClockImpl::time_point m_refPoint{priv::ClockImpl::now()}; //!< Time of last reset ClockImpl::time_point m_refPoint{ClockImpl::now()}; //!< Time of last reset
priv::ClockImpl::time_point m_stopPoint; //!< Time of last stop ClockImpl::time_point m_stopPoint; //!< Time of last stop
}; };
} // namespace sf } // namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Clock /// \class Clock
/// \ingroup system /// \ingroup system
/// ///
/// `sf::Clock` is a lightweight class for measuring time. /// `Clock` is a lightweight class for measuring time.
/// ///
/// It provides the most precise time that the underlying /// It provides the most precise time that the underlying
/// OS can achieve (generally microseconds or nanoseconds). /// OS can achieve (generally microseconds or nanoseconds).
@@ -178,7 +174,7 @@ private:
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// sf::Clock clock; /// Clock clock;
/// ... /// ...
/// Time time1 = clock.getElapsedTime(); /// Time time1 = clock.getElapsedTime();
/// ... /// ...
@@ -187,10 +183,10 @@ private:
/// Time time3 = clock.reset(); /// Time time3 = clock.reset();
/// \endcode /// \endcode
/// ///
/// The `sf::Time` value returned by the clock can then be /// The `Time` value returned by the clock can then be
/// converted to a number of seconds, milliseconds or even /// converted to a number of seconds, milliseconds or even
/// microseconds. /// microseconds.
/// ///
/// \see `sf::Time` /// \see `Time`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -44,10 +44,10 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \fn sf::err /// \fn err
/// \ingroup system /// \ingroup system
/// ///
/// By default, `sf::err()` outputs to the same location as `std::cerr`, /// By default, `err()` outputs to the same location as `std::cerr`,
/// (-> the stderr descriptor) which is the console if there's /// (-> the stderr descriptor) which is the console if there's
/// one available. /// one available.
/// ///
@@ -55,7 +55,7 @@ namespace sf
/// insertion operations defined by the STL /// insertion operations defined by the STL
/// (`operator<<`, manipulators, etc.). /// (`operator<<`, manipulators, etc.).
/// ///
/// `sf::err()` can be redirected to write to another output, independently /// `err()` can be redirected to write to another output, independently
/// of `std::cerr`, by using the `rdbuf()` function provided by the /// of `std::cerr`, by using the `rdbuf()` function provided by the
/// `std::ostream` class. /// `std::ostream` class.
/// ///
@@ -63,13 +63,13 @@ namespace sf
/// \code /// \code
/// // Redirect to a file /// // Redirect to a file
/// std::ofstream file("sfml-log.txt"); /// std::ofstream file("sfml-log.txt");
/// std::streambuf* previous = sf::err().rdbuf(file.rdbuf()); /// std::streambuf* previous = err().rdbuf(file.rdbuf());
/// ///
/// // Redirect to nothing /// // Redirect to nothing
/// sf::err().rdbuf(nullptr); /// err().rdbuf(nullptr);
/// ///
/// // Restore the original output /// // Restore the original output
/// sf::err().rdbuf(previous); /// err().rdbuf(previous);
/// \endcode /// \endcode
/// ///
/// \return Reference to `std::ostream` representing the SFML error stream /// \return Reference to `std::ostream` representing the SFML error stream

View File

@@ -33,14 +33,14 @@
#include <SFML/System/InputStream.hpp> #include <SFML/System/InputStream.hpp>
#include <filesystem> #include "filesystem.hpp"
#include <memory> #include <memory>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
namespace sf::priv namespace sf
{ {
class SFML_SYSTEM_API ResourceStream; class SFML_SYSTEM_API ResourceStream;
} }
@@ -100,10 +100,10 @@ public:
/// ///
/// \param filename Name of the file to open /// \param filename Name of the file to open
/// ///
/// \throws sf::Exception on error /// \throws Exception on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
explicit FileInputStream(const std::filesystem::path& filename); explicit FileInputStream(const ghc::filesystem::path& filename);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Open the stream from a file path /// \brief Open the stream from a file path
@@ -113,7 +113,7 @@ public:
/// \return `true` on success, `false` on error /// \return `true` on success, `false` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool open(const std::filesystem::path& filename); [[nodiscard]] bool open(const ghc::filesystem::path& filename);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Read data from the stream /// \brief Read data from the stream
@@ -124,36 +124,36 @@ public:
/// \param data Buffer where to copy the read data /// \param data Buffer where to copy the read data
/// \param size Desired number of bytes to read /// \param size Desired number of bytes to read
/// ///
/// \return The number of bytes actually read, or `std::nullopt` on error /// \return The number of bytes actually read, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override; [[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Change the current reading position /// \brief Change the current reading position
/// ///
/// \param position The position to seek to, from the beginning /// \param position The position to seek to, from the beginning
/// ///
/// \return The position actually sought to, or `std::nullopt` on error /// \return The position actually sought to, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override; [[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the current reading position in the stream /// \brief Get the current reading position in the stream
/// ///
/// \return The current position, or `std::nullopt` on error. /// \return The current position, or `nonstd::nullopt` on error.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> tell() override; [[nodiscard]] nonstd::optional<std::size_t> tell() override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the size of the stream /// \brief Return the size of the stream
/// ///
/// \return The total number of bytes available in the stream, or `std::nullopt` on error /// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> getSize() override; nonstd::optional<std::size_t> getSize() override;
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -169,7 +169,7 @@ private:
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
std::unique_ptr<priv::ResourceStream> m_androidFile; std::unique_ptr<ResourceStream> m_androidFile;
#endif #endif
std::unique_ptr<std::FILE, FileCloser> m_file; //!< stdio file stream std::unique_ptr<std::FILE, FileCloser> m_file; //!< stdio file stream
@@ -179,7 +179,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::FileInputStream /// \class FileInputStream
/// \ingroup system /// \ingroup system
/// ///
/// This class is a specialization of `InputStream` that /// This class is a specialization of `InputStream` that
@@ -202,7 +202,7 @@ private:
/// \code /// \code
/// void process(InputStream& stream); /// void process(InputStream& stream);
/// ///
/// std::optional stream = sf::FileInputStream::open("some_file.dat"); /// nonstd::optional stream = FileInputStream::open("some_file.dat");
/// if (stream) /// if (stream)
/// process(*stream); /// process(*stream);
/// \endcode /// \endcode

View File

@@ -31,7 +31,7 @@
#include <SFML/System/Export.hpp> #include <SFML/System/Export.hpp>
#include <optional> #include <optional.hpp>
#include <cstdint> #include <cstdint>
@@ -60,74 +60,74 @@ public:
/// \param data Buffer where to copy the read data /// \param data Buffer where to copy the read data
/// \param size Desired number of bytes to read /// \param size Desired number of bytes to read
/// ///
/// \return The number of bytes actually read, or `std::nullopt` on error /// \return The number of bytes actually read, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] virtual std::optional<std::size_t> read(void* data, std::size_t size) = 0; [[nodiscard]] virtual nonstd::optional<std::size_t> read(void* data, std::size_t size) = 0;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Change the current reading position /// \brief Change the current reading position
/// ///
/// \param position The position to seek to, from the beginning /// \param position The position to seek to, from the beginning
/// ///
/// \return The position actually sought to, or `std::nullopt` on error /// \return The position actually sought to, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] virtual std::optional<std::size_t> seek(std::size_t position) = 0; [[nodiscard]] virtual nonstd::optional<std::size_t> seek(std::size_t position) = 0;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the current reading position in the stream /// \brief Get the current reading position in the stream
/// ///
/// \return The current position, or `std::nullopt` on error. /// \return The current position, or `nonstd::nullopt` on error.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] virtual std::optional<std::size_t> tell() = 0; [[nodiscard]] virtual nonstd::optional<std::size_t> tell() = 0;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the size of the stream /// \brief Return the size of the stream
/// ///
/// \return The total number of bytes available in the stream, or `std::nullopt` on error /// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual std::optional<std::size_t> getSize() = 0; virtual nonstd::optional<std::size_t> getSize() = 0;
}; };
} // namespace sf } // namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::InputStream /// \class InputStream
/// \ingroup system /// \ingroup system
/// ///
/// This class allows users to define their own file input sources /// This class allows users to define their own file input sources
/// from which SFML can load resources. /// from which SFML can load resources.
/// ///
/// SFML resource classes like `sf::Texture` and /// SFML resource classes like `Texture` and
/// `sf::SoundBuffer` provide `loadFromFile` and `loadFromMemory` functions, /// `SoundBuffer` provide `loadFromFile` and `loadFromMemory` functions,
/// which read data from conventional sources. However, if you /// which read data from conventional sources. However, if you
/// have data coming from a different source (over a network, /// have data coming from a different source (over a network,
/// embedded, encrypted, compressed, etc) you can derive your /// embedded, encrypted, compressed, etc) you can derive your
/// own class from `sf::InputStream` and load SFML resources with /// own class from `InputStream` and load SFML resources with
/// their `loadFromStream` function. /// their `loadFromStream` function.
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// // custom stream class that reads from inside a zip file /// // custom stream class that reads from inside a zip file
/// class ZipStream : public sf::InputStream /// class ZipStream : public InputStream
/// { /// {
/// public: /// public:
/// ///
/// ZipStream(const std::string& archive); /// ZipStream(const std::string& archive);
/// ///
/// [[nodiscard]] bool open(const std::filesystem::path& filename); /// [[nodiscard]] bool open(const ghc::filesystem::path& filename);
/// ///
/// [[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size); /// [[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size);
/// ///
/// [[nodiscard]] std::optional<std::size_t> seek(std::size_t position); /// [[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position);
/// ///
/// [[nodiscard]] std::optional<std::size_t> tell(); /// [[nodiscard]] nonstd::optional<std::size_t> tell();
/// ///
/// std::optional<std::size_t> getSize(); /// nonstd::optional<std::size_t> getSize();
/// ///
/// private: /// private:
/// ///
@@ -142,10 +142,10 @@ public:
/// // Handle error... /// // Handle error...
/// } /// }
/// ///
/// const sf::Texture texture(stream); /// const Texture texture(stream);
/// ///
/// // musics... /// // musics...
/// sf::Music music; /// Music music;
/// ZipStream stream("resources.zip"); /// ZipStream stream("resources.zip");
/// ///
/// if (!stream.open("musics/msc.ogg")) /// if (!stream.open("musics/msc.ogg"))

View File

@@ -64,42 +64,42 @@ public:
/// \param data Buffer where to copy the read data /// \param data Buffer where to copy the read data
/// \param size Desired number of bytes to read /// \param size Desired number of bytes to read
/// ///
/// \return The number of bytes actually read, or `std::nullopt` on error /// \return The number of bytes actually read, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override; [[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Change the current reading position /// \brief Change the current reading position
/// ///
/// \param position The position to seek to, from the beginning /// \param position The position to seek to, from the beginning
/// ///
/// \return The position actually sought to, or `std::nullopt` on error /// \return The position actually sought to, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override; [[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the current reading position in the stream /// \brief Get the current reading position in the stream
/// ///
/// \return The current position, or `std::nullopt` on error. /// \return The current position, or `nonstd::nullopt` on error.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] std::optional<std::size_t> tell() override; [[nodiscard]] nonstd::optional<std::size_t> tell() override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the size of the stream /// \brief Return the size of the stream
/// ///
/// \return The total number of bytes available in the stream, or `std::nullopt` on error /// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> getSize() override; nonstd::optional<std::size_t> getSize() override;
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const std::byte* m_data{}; //!< Pointer to the data in memory const unsigned char* m_data{}; //!< Pointer to the data in memory
std::size_t m_size{}; //!< Total size of the data std::size_t m_size{}; //!< Total size of the data
std::size_t m_offset{}; //!< Current reading position std::size_t m_offset{}; //!< Current reading position
}; };
@@ -108,7 +108,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::MemoryInputStream /// \class MemoryInputStream
/// \ingroup system /// \ingroup system
/// ///
/// This class is a specialization of `InputStream` that /// This class is a specialization of `InputStream` that

View File

@@ -38,13 +38,13 @@ class Time;
/// \ingroup system /// \ingroup system
/// \brief Make the current thread sleep for a given duration /// \brief Make the current thread sleep for a given duration
/// ///
/// `sf::sleep` is the best way to block a program or one of its /// `sleep` is the best way to block a program or one of its
/// threads, as it doesn't consume any CPU power. Compared to /// threads, as it doesn't consume any CPU power. Compared to
/// the standard `std::this_thread::sleep_for` function, this /// the standard `std::this_thread::sleep_for` function, this
/// one provides more accurate sleeping time thanks to some /// one provides more accurate sleeping time thanks to some
/// platform-specific tweaks. /// platform-specific tweaks.
/// ///
/// `sf::sleep` only guarantees millisecond precision. Sleeping /// `sleep` only guarantees millisecond precision. Sleeping
/// for a duration less than 1 millisecond is prone to result /// for a duration less than 1 millisecond is prone to result
/// in the actual sleep duration being less than what is /// in the actual sleep duration being less than what is
/// requested. /// requested.

View File

@@ -99,7 +99,7 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// NOLINTBEGIN(readability-identifier-naming) // NOLINTBEGIN(readability-identifier-naming)
/// Represents an invalid position in the string /// Represents an invalid position in the string
static inline const std::size_t InvalidPos{std::u32string::npos}; static const std::size_t InvalidPos{std::u32string::npos};
// NOLINTEND(readability-identifier-naming) // NOLINTEND(readability-identifier-naming)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -203,12 +203,12 @@ public:
String(std::u32string utf32String); String(std::u32string utf32String);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new `sf::String` from a UTF-8 encoded string /// \brief Create a new `String` from a UTF-8 encoded string
/// ///
/// \param begin Forward iterator to the beginning of the UTF-8 sequence /// \param begin Forward iterator to the beginning of the UTF-8 sequence
/// \param end Forward iterator to the end of the UTF-8 sequence /// \param end Forward iterator to the end of the UTF-8 sequence
/// ///
/// \return A `sf::String` containing the source string /// \return A `String` containing the source string
/// ///
/// \see `fromUtf16`, `fromUtf32` /// \see `fromUtf16`, `fromUtf32`
/// ///
@@ -217,12 +217,12 @@ public:
[[nodiscard]] static String fromUtf8(T begin, T end); [[nodiscard]] static String fromUtf8(T begin, T end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new `sf::String` from a UTF-16 encoded string /// \brief Create a new `String` from a UTF-16 encoded string
/// ///
/// \param begin Forward iterator to the beginning of the UTF-16 sequence /// \param begin Forward iterator to the beginning of the UTF-16 sequence
/// \param end Forward iterator to the end of the UTF-16 sequence /// \param end Forward iterator to the end of the UTF-16 sequence
/// ///
/// \return A `sf::String` containing the source string /// \return A `String` containing the source string
/// ///
/// \see `fromUtf8`, `fromUtf32` /// \see `fromUtf8`, `fromUtf32`
/// ///
@@ -231,7 +231,7 @@ public:
[[nodiscard]] static String fromUtf16(T begin, T end); [[nodiscard]] static String fromUtf16(T begin, T end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new `sf::String` from a UTF-32 encoded string /// \brief Create a new `String` from a UTF-32 encoded string
/// ///
/// This function is provided for consistency, it is equivalent to /// This function is provided for consistency, it is equivalent to
/// using the constructors that takes a `const char32_t*` or /// using the constructors that takes a `const char32_t*` or
@@ -240,7 +240,7 @@ public:
/// \param begin Forward iterator to the beginning of the UTF-32 sequence /// \param begin Forward iterator to the beginning of the UTF-32 sequence
/// \param end Forward iterator to the end of the UTF-32 sequence /// \param end Forward iterator to the end of the UTF-32 sequence
/// ///
/// \return A `sf::String` containing the source string /// \return A `String` containing the source string
/// ///
/// \see `fromUtf8`, `fromUtf16` /// \see `fromUtf8`, `fromUtf16`
/// ///
@@ -318,7 +318,7 @@ public:
/// \see `toUtf16`, `toUtf32` /// \see `toUtf16`, `toUtf32`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] sf::U8String toUtf8() const; [[nodiscard]] U8String toUtf8() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert the Unicode string to a UTF-16 string /// \brief Convert the Unicode string to a UTF-16 string
@@ -651,10 +651,10 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::String /// \class String
/// \ingroup system /// \ingroup system
/// ///
/// `sf::String` is a utility string class defined mainly for /// `String` is a utility string class defined mainly for
/// convenience. It is a Unicode string (implemented using /// convenience. It is a Unicode string (implemented using
/// UTF-32), thus it can store any character in the world /// UTF-32), thus it can store any character in the world
/// (European, Chinese, Arabic, Hebrew, etc.). /// (European, Chinese, Arabic, Hebrew, etc.).
@@ -662,10 +662,10 @@ private:
/// It automatically handles conversions from/to ANSI and /// It automatically handles conversions from/to ANSI and
/// wide strings, so that you can work with standard string /// wide strings, so that you can work with standard string
/// classes and still be compatible with functions taking a /// classes and still be compatible with functions taking a
/// `sf::String`. /// `String`.
/// ///
/// \code /// \code
/// sf::String s; /// String s;
/// ///
/// std::string s1 = s; // automatically converted to ANSI string /// std::string s1 = s; // automatically converted to ANSI string
/// std::wstring s2 = s; // automatically converted to wide string /// std::wstring s2 = s; // automatically converted to wide string
@@ -679,22 +679,22 @@ private:
/// it is possible to use a custom locale if necessary: /// it is possible to use a custom locale if necessary:
/// \code /// \code
/// std::locale locale; /// std::locale locale;
/// sf::String s; /// String s;
/// ... /// ...
/// std::string s1 = s.toAnsiString(locale); /// std::string s1 = s.toAnsiString(locale);
/// s = sf::String("hello", locale); /// s = String("hello", locale);
/// \endcode /// \endcode
/// ///
/// `sf::String` defines the most important functions of the /// `String` defines the most important functions of the
/// standard `std::string` class: removing, random access, iterating, /// standard `std::string` class: removing, random access, iterating,
/// appending, comparing, etc. However it is a simple class /// appending, comparing, etc. However it is a simple class
/// provided for convenience, and you may have to consider using /// provided for convenience, and you may have to consider using
/// a more optimized class if your program requires complex string /// a more optimized class if your program requires complex string
/// handling. The automatic conversion functions will then take /// handling. The automatic conversion functions will then take
/// care of converting your string to `sf::String` whenever SFML /// care of converting your string to `String` whenever SFML
/// requires it. /// requires it.
/// ///
/// Please note that SFML also defines a low-level, generic /// Please note that SFML also defines a low-level, generic
/// interface for Unicode handling, see the `sf::Utf` classes. /// interface for Unicode handling, see the `Utf` classes.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -448,17 +448,17 @@ constexpr Time& operator%=(Time& left, Time right);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Time /// \class Time
/// \ingroup system /// \ingroup system
/// ///
/// `sf::Time` encapsulates a time value in a flexible way. /// `Time` encapsulates a time value in a flexible way.
/// It allows to define a time value either as a number of /// It allows to define a time value either as a number of
/// seconds, milliseconds or microseconds. It also works the /// seconds, milliseconds or microseconds. It also works the
/// other way round: you can read a time value as either /// other way round: you can read a time value as either
/// a number of seconds, milliseconds or microseconds. It /// a number of seconds, milliseconds or microseconds. It
/// even interoperates with the `<chrono>` header. You can /// even interoperates with the `<chrono>` header. You can
/// construct an `sf::Time` from a `chrono::duration` and read /// construct an `Time` from a `chrono::duration` and read
/// any `sf::Time` as a chrono::duration. /// any `Time` as a chrono::duration.
/// ///
/// By using such a flexible interface, the API doesn't /// By using such a flexible interface, the API doesn't
/// impose any fixed type or resolution for time values, /// impose any fixed type or resolution for time values,
@@ -473,28 +473,28 @@ constexpr Time& operator%=(Time& left, Time right);
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// sf::Time t1 = sf::seconds(0.1f); /// Time t1 = seconds(0.1f);
/// std::int32_t milli = t1.asMilliseconds(); // 100 /// std::int32_t milli = t1.asMilliseconds(); // 100
/// ///
/// sf::Time t2 = sf::milliseconds(30); /// Time t2 = milliseconds(30);
/// std::int64_t micro = t2.asMicroseconds(); // 30'000 /// std::int64_t micro = t2.asMicroseconds(); // 30'000
/// ///
/// sf::Time t3 = sf::microseconds(-800'000); /// Time t3 = microseconds(-800'000);
/// float sec = t3.asSeconds(); // -0.8 /// float sec = t3.asSeconds(); // -0.8
/// ///
/// sf::Time t4 = std::chrono::milliseconds(250); /// Time t4 = std::chrono::milliseconds(250);
/// std::chrono::microseconds micro2 = t4.toDuration(); // 250'000us /// std::chrono::microseconds micro2 = t4.toDuration(); // 250'000us
/// \endcode /// \endcode
/// ///
/// \code /// \code
/// void update(sf::Time elapsed) /// void update(Time elapsed)
/// { /// {
/// position += speed * elapsed.asSeconds(); /// position += speed * elapsed.asSeconds();
/// } /// }
/// ///
/// update(sf::milliseconds(100)); /// update(milliseconds(100));
/// \endcode /// \endcode
/// ///
/// \see `sf::Clock` /// \see `Clock`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -279,6 +279,6 @@ constexpr Time& operator%=(Time& left, Time right)
// Note: the 'inline' keyword here is technically not required, but VS2019 fails // Note: the 'inline' keyword here is technically not required, but VS2019 fails
// to compile with a bogus "multiple definition" error if not explicitly used. // to compile with a bogus "multiple definition" error if not explicitly used.
inline constexpr Time Time::Zero; constexpr Time Time::Zero;
} // namespace sf } // namespace sf

View File

@@ -207,7 +207,7 @@ public:
/// ///
/// This functions does nothing more than a direct copy; /// This functions does nothing more than a direct copy;
/// it is defined only to provide the same interface as other /// it is defined only to provide the same interface as other
/// specializations of the `sf::Utf<>` template, and allow /// specializations of the `Utf<>` template, and allow
/// generic code to be written on top of it. /// generic code to be written on top of it.
/// ///
/// \param begin Iterator pointing to the beginning of the input sequence /// \param begin Iterator pointing to the beginning of the input sequence
@@ -426,7 +426,7 @@ public:
/// ///
/// This functions does nothing more than a direct copy; /// This functions does nothing more than a direct copy;
/// it is defined only to provide the same interface as other /// it is defined only to provide the same interface as other
/// specializations of the `sf::Utf<>` template, and allow /// specializations of the `Utf<>` template, and allow
/// generic code to be written on top of it. /// generic code to be written on top of it.
/// ///
/// \param begin Iterator pointing to the beginning of the input sequence /// \param begin Iterator pointing to the beginning of the input sequence
@@ -646,7 +646,7 @@ public:
/// ///
/// This functions does nothing more than a direct copy; /// This functions does nothing more than a direct copy;
/// it is defined only to provide the same interface as other /// it is defined only to provide the same interface as other
/// specializations of the `sf::Utf<>` template, and allow /// specializations of the `Utf<>` template, and allow
/// generic code to be written on top of it. /// generic code to be written on top of it.
/// ///
/// \param begin Iterator pointing to the beginning of the input sequence /// \param begin Iterator pointing to the beginning of the input sequence
@@ -663,7 +663,7 @@ public:
/// \brief Decode a single ANSI character to UTF-32 /// \brief Decode a single ANSI character to UTF-32
/// ///
/// This function does not exist in other specializations /// This function does not exist in other specializations
/// of `sf::Utf<>`, it is defined for convenience (it is used by /// of `Utf<>`, it is defined for convenience (it is used by
/// several other conversion functions). /// several other conversion functions).
/// ///
/// \param input Input ANSI character /// \param input Input ANSI character
@@ -679,7 +679,7 @@ public:
/// \brief Decode a single wide character to UTF-32 /// \brief Decode a single wide character to UTF-32
/// ///
/// This function does not exist in other specializations /// This function does not exist in other specializations
/// of `sf::Utf<>`, it is defined for convenience (it is used by /// of `Utf<>`, it is defined for convenience (it is used by
/// several other conversion functions). /// several other conversion functions).
/// ///
/// \param input Input wide character /// \param input Input wide character
@@ -694,7 +694,7 @@ public:
/// \brief Encode a single UTF-32 character to ANSI /// \brief Encode a single UTF-32 character to ANSI
/// ///
/// This function does not exist in other specializations /// This function does not exist in other specializations
/// of `sf::Utf<>`, it is defined for convenience (it is used by /// of `Utf<>`, it is defined for convenience (it is used by
/// several other conversion functions). /// several other conversion functions).
/// ///
/// \param codepoint Iterator pointing to the beginning of the input sequence /// \param codepoint Iterator pointing to the beginning of the input sequence
@@ -712,7 +712,7 @@ public:
/// \brief Encode a single UTF-32 character to wide /// \brief Encode a single UTF-32 character to wide
/// ///
/// This function does not exist in other specializations /// This function does not exist in other specializations
/// of `sf::Utf<>`, it is defined for convenience (it is used by /// of `Utf<>`, it is defined for convenience (it is used by
/// several other conversion functions). /// several other conversion functions).
/// ///
/// \param codepoint Iterator pointing to the beginning of the input sequence /// \param codepoint Iterator pointing to the beginning of the input sequence
@@ -737,22 +737,22 @@ using Utf32 = Utf<32>;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Utf /// \class Utf
/// \ingroup system /// \ingroup system
/// ///
/// Utility class providing generic functions for UTF conversions. /// Utility class providing generic functions for UTF conversions.
/// ///
/// `sf::Utf` is a low-level, generic interface for counting, iterating, /// `Utf` is a low-level, generic interface for counting, iterating,
/// encoding and decoding Unicode characters and strings. It is able /// encoding and decoding Unicode characters and strings. It is able
/// to handle ANSI, wide, latin-1, UTF-8, UTF-16 and UTF-32 encodings. /// to handle ANSI, wide, latin-1, UTF-8, UTF-16 and UTF-32 encodings.
/// ///
/// `sf::Utf<X>` functions are all static, these classes are not meant to /// `Utf<X>` functions are all static, these classes are not meant to
/// be instantiated. All the functions are template, so that you /// be instantiated. All the functions are template, so that you
/// can use any character / string type for a given encoding. /// can use any character / string type for a given encoding.
/// ///
/// It has 3 specializations: /// It has 3 specializations:
/// \li `sf::Utf<8>` (with `sf::Utf8` type alias) /// \li `Utf<8>` (with `Utf8` type alias)
/// \li `sf::Utf<16>` (with `sf::Utf16` type alias) /// \li `Utf<16>` (with `Utf16` type alias)
/// \li `sf::Utf<32>` (with `sf::Utf32` type alias) /// \li `Utf<32>` (with `Utf32` type alias)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -1,4 +1,4 @@
//////////////////////////////////////////////////////////// ///////i///////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) // Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org)
@@ -43,8 +43,6 @@
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out copyBits(In begin, In end, Out output) Out copyBits(In begin, In end, Out output)
@@ -74,7 +72,6 @@ Out copyBits(In begin, In end, Out output)
return output; return output;
} }
} // namespace priv
template <typename In> template <typename In>
In Utf<8>::decode(In begin, In end, char32_t& output, char32_t replacement) In Utf<8>::decode(In begin, In end, char32_t& output, char32_t replacement)
@@ -174,7 +171,7 @@ Out Utf<8>::encode(char32_t input, Out output, std::uint8_t replacement)
// clang-format on // clang-format on
// Add them to the output // Add them to the output
output = priv::copyBits(bytes.data(), bytes.data() + bytestoWrite, output); output = copyBits(bytes.data(), bytes.data() + bytestoWrite, output);
} }
return output; return output;
@@ -315,7 +312,7 @@ Out Utf<8>::toUtf8(In begin, In end, Out output)
{ {
static_assert(sizeof(decltype(*begin)) == sizeof(char)); static_assert(sizeof(decltype(*begin)) == sizeof(char));
return priv::copyBits(begin, end, output); return copyBits(begin, end, output);
} }
@@ -500,7 +497,7 @@ Out Utf<16>::fromLatin1(In begin, In end, Out output)
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
return priv::copyBits(begin, end, output); return copyBits(begin, end, output);
} }
@@ -579,7 +576,7 @@ Out Utf<16>::toUtf16(In begin, In end, Out output)
{ {
static_assert(sizeof(decltype(*begin)) == sizeof(char16_t)); static_assert(sizeof(decltype(*begin)) == sizeof(char16_t));
return priv::copyBits(begin, end, output); return copyBits(begin, end, output);
} }
@@ -674,7 +671,7 @@ Out Utf<32>::fromLatin1(In begin, In end, Out output)
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
return priv::copyBits(begin, end, output); return copyBits(begin, end, output);
} }
@@ -753,7 +750,7 @@ Out Utf<32>::toUtf32(In begin, In end, Out output)
{ {
static_assert(sizeof(decltype(*begin)) == sizeof(char32_t)); static_assert(sizeof(decltype(*begin)) == sizeof(char32_t));
return priv::copyBits(begin, end, output); return copyBits(begin, end, output);
} }

View File

@@ -386,10 +386,10 @@ template <typename T>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Vector2 /// \class Vector2
/// \ingroup system /// \ingroup system
/// ///
/// `sf::Vector2` is a simple class that defines a mathematical /// `Vector2` is a simple class that defines a mathematical
/// vector with two coordinates (x and y). It can be used to /// vector with two coordinates (x and y). It can be used to
/// represent anything that has two dimensions: a size, a point, /// represent anything that has two dimensions: a size, a point,
/// a velocity, a scale, etc. /// a velocity, a scale, etc.
@@ -406,23 +406,23 @@ template <typename T>
/// results cannot be represented accurately with integers. /// results cannot be represented accurately with integers.
/// The method documentation mentions "(floating-point)" in those cases. /// The method documentation mentions "(floating-point)" in those cases.
/// ///
/// You generally don't have to care about the templated form (`sf::Vector2<T>`), /// You generally don't have to care about the templated form (`Vector2<T>`),
/// the most common specializations have special type aliases: /// the most common specializations have special type aliases:
/// \li `sf::Vector2<float>` is `sf::Vector2f` /// \li `Vector2<float>` is `Vector2f`
/// \li `sf::Vector2<int>` is `sf::Vector2i` /// \li `Vector2<int>` is `Vector2i`
/// \li `sf::Vector2<unsigned int>` is `sf::Vector2u` /// \li `Vector2<unsigned int>` is `Vector2u`
/// ///
/// The `sf::Vector2` class has a simple interface, its x and y members /// The `Vector2` class has a simple interface, its x and y members
/// can be accessed directly (there are no accessors like setX(), getX()). /// can be accessed directly (there are no accessors like setX(), getX()).
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// sf::Vector2f v(16.5f, 24.f); /// Vector2f v(16.5f, 24.f);
/// v.x = 18.2f; /// v.x = 18.2f;
/// float y = v.y; /// float y = v.y;
/// ///
/// sf::Vector2f w = v * 5.f; /// Vector2f w = v * 5.f;
/// sf::Vector2f u; /// Vector2f u;
/// u = v + w; /// u = v + w;
/// ///
/// float s = v.dot(w); /// float s = v.dot(w);
@@ -430,6 +430,6 @@ template <typename T>
/// bool different = (v != u); /// bool different = (v != u);
/// \endcode /// \endcode
/// ///
/// Note: for 3-dimensional vectors, see `sf::Vector3`. /// Note: for 3-dimensional vectors, see `Vector3`.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -311,10 +311,10 @@ using Vector3f = Vector3<float>;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Vector3 /// \class Vector3
/// \ingroup system /// \ingroup system
/// ///
/// `sf::Vector3` is a simple class that defines a mathematical /// `Vector3` is a simple class that defines a mathematical
/// vector with three coordinates (x, y and z). It can be used to /// vector with three coordinates (x, y and z). It can be used to
/// represent anything that has three dimensions: a size, a point, /// represent anything that has three dimensions: a size, a point,
/// a velocity, etc. /// a velocity, etc.
@@ -327,30 +327,30 @@ using Vector3f = Vector3<float>;
/// results cannot be represented accurately with integers. /// results cannot be represented accurately with integers.
/// The method documentation mentions "(floating-point)" in those cases. /// The method documentation mentions "(floating-point)" in those cases.
/// ///
/// You generally don't have to care about the templated form (`sf::Vector3<T>`), /// You generally don't have to care about the templated form (`Vector3<T>`),
/// the most common specializations have special type aliases: /// the most common specializations have special type aliases:
/// \li `sf::Vector3<float>` is `sf::Vector3f` /// \li `Vector3<float>` is `Vector3f`
/// \li `sf::Vector3<int>` is `sf::Vector3i` /// \li `Vector3<int>` is `Vector3i`
/// ///
/// The `sf::Vector3` class has a small and simple interface, its x, y and z members /// The `Vector3` class has a small and simple interface, its x, y and z members
/// can be accessed directly (there are no accessors like `setX()`, `getX()`). /// can be accessed directly (there are no accessors like `setX()`, `getX()`).
/// ///
/// Usage example: /// Usage example:
/// \code /// \code
/// sf::Vector3f v(16.5f, 24.f, -3.2f); /// Vector3f v(16.5f, 24.f, -3.2f);
/// v.x = 18.2f; /// v.x = 18.2f;
/// float y = v.y; /// float y = v.y;
/// ///
/// sf::Vector3f w = v * 5.f; /// Vector3f w = v * 5.f;
/// sf::Vector3f u; /// Vector3f u;
/// u = v + w; /// u = v + w;
/// ///
/// float s = v.dot(w); /// float s = v.dot(w);
/// sf::Vector3f t = v.cross(w); /// Vector3f t = v.cross(w);
/// ///
/// bool different = (v != u); /// bool different = (v != u);
/// \endcode /// \endcode
/// ///
/// Note: for 2-dimensional vectors, see `sf::Vector2`. /// Note: for 2-dimensional vectors, see `Vector2`.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@@ -5,6 +5,7 @@ set(SRCROOT ${PROJECT_SOURCE_DIR}/src/SFML/Network)
# all source files # all source files
set(SRC set(SRC
${INCROOT}/../Network.hpp
${INCROOT}/Export.hpp ${INCROOT}/Export.hpp
${INCROOT}/Ftp.hpp ${INCROOT}/Ftp.hpp
${INCROOT}/Http.hpp ${INCROOT}/Http.hpp
@@ -46,9 +47,10 @@ source_group("" FILES ${SRC})
# define the sfml-network target # define the sfml-network target
add_library(sfml-network ${SRC}) add_library(sfml-network ${SRC})
target_include_directories(sfml-network PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR}/../../../include) target_include_directories(sfml-network PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR}/../../../include ${NONSTD_INCLUDE_DIR})
target_compile_definitions(sfml-network PRIVATE SFML_STATIC) target_compile_definitions(sfml-network PRIVATE SFML_STATIC)
target_compile_definitions(sfml-network INTERFACE SFML_STATIC)
# setup dependencies # setup dependencies
target_link_libraries(sfml-network PUBLIC sfml-system) target_link_libraries(sfml-network PUBLIC sfml-system)

View File

@@ -122,7 +122,7 @@ Ftp::DirectoryResponse::DirectoryResponse(const Ftp::Response& response) : Ftp::
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const std::filesystem::path& Ftp::DirectoryResponse::getDirectory() const const ghc::filesystem::path& Ftp::DirectoryResponse::getDirectory() const
{ {
return m_directory; return m_directory;
} }
@@ -268,7 +268,7 @@ Ftp::Response Ftp::deleteDirectory(const std::string& name)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Ftp::Response Ftp::renameFile(const std::filesystem::path& file, const std::filesystem::path& newName) Ftp::Response Ftp::renameFile(const ghc::filesystem::path& file, const ghc::filesystem::path& newName)
{ {
Response response = sendCommand("RNFR", file.string()); Response response = sendCommand("RNFR", file.string());
if (response.isOk()) if (response.isOk())
@@ -279,14 +279,14 @@ Ftp::Response Ftp::renameFile(const std::filesystem::path& file, const std::file
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Ftp::Response Ftp::deleteFile(const std::filesystem::path& name) Ftp::Response Ftp::deleteFile(const ghc::filesystem::path& name)
{ {
return sendCommand("DELE", name.string()); return sendCommand("DELE", name.string());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::filesystem::path& localPath, TransferMode mode) Ftp::Response Ftp::download(const ghc::filesystem::path& remoteFile, const ghc::filesystem::path& localPath, TransferMode mode)
{ {
// Open a data channel using the given transfer mode // Open a data channel using the given transfer mode
DataChannel data(*this); DataChannel data(*this);
@@ -298,7 +298,7 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
if (response.isOk()) if (response.isOk())
{ {
// Create the file and truncate it if necessary // Create the file and truncate it if necessary
const std::filesystem::path filepath = localPath / remoteFile.filename(); const ghc::filesystem::path filepath = localPath / remoteFile.filename();
std::ofstream file(filepath, std::ios_base::binary | std::ios_base::trunc); std::ofstream file(filepath, std::ios_base::binary | std::ios_base::trunc);
if (!file) if (!file)
return Response(Response::Status::InvalidFile); return Response(Response::Status::InvalidFile);
@@ -314,7 +314,7 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
// If the download was unsuccessful, delete the partial file // If the download was unsuccessful, delete the partial file
if (!response.isOk()) if (!response.isOk())
std::filesystem::remove(filepath); ghc::filesystem::remove(filepath);
} }
} }
@@ -323,8 +323,8 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Ftp::Response Ftp::upload(const std::filesystem::path& localFile, Ftp::Response Ftp::upload(const ghc::filesystem::path& localFile,
const std::filesystem::path& remotePath, const ghc::filesystem::path& remotePath,
TransferMode mode, TransferMode mode,
bool append) bool append)
{ {

View File

@@ -123,9 +123,10 @@ std::string Http::Request::prepare() const
out << "HTTP/" << m_majorVersion << "." << m_minorVersion << "\r\n"; out << "HTTP/" << m_majorVersion << "." << m_minorVersion << "\r\n";
// Write fields // Write fields
for (const auto& [fieldKey, fieldValue] : m_fields) auto it = m_fields.begin();
for (; it != m_fields.end(); it++)
{ {
out << fieldKey << ": " << fieldValue << "\r\n"; out << it->first << ": " << it->second << "\r\n";
} }
// Use an extra \r\n to separate the header from the body // Use an extra \r\n to separate the header from the body
@@ -148,7 +149,8 @@ bool Http::Request::hasField(const std::string& field) const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const std::string& Http::Response::getField(const std::string& field) const const std::string& Http::Response::getField(const std::string& field) const
{ {
if (const auto it = m_fields.find(toLower(field)); it != m_fields.end()) const auto it = m_fields.find(toLower(field));
if (it != m_fields.end())
{ {
return it->second; return it->second;
} }
@@ -310,7 +312,7 @@ void Http::setHost(const std::string& host, unsigned short port)
else if (toLower(host.substr(0, 8)) == "https://") else if (toLower(host.substr(0, 8)) == "https://")
{ {
// HTTPS protocol -- unsupported (requires encryption and certificates and stuff...) // HTTPS protocol -- unsupported (requires encryption and certificates and stuff...)
err() << "HTTPS protocol is not supported by sf::Http" << std::endl; err() << "HTTPS protocol is not supported by Http" << std::endl;
m_hostName.clear(); m_hostName.clear();
m_port = 0; m_port = 0;
} }

View File

@@ -46,28 +46,27 @@ const IpAddress IpAddress::Broadcast(255, 255, 255, 255);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<IpAddress> IpAddress::resolve(std::string_view address) nonstd::optional<IpAddress> IpAddress::resolve(std::string address)
{ {
using namespace std::string_view_literals;
if (address.empty()) if (address.empty())
{ {
// Not generating en error message here as resolution failure is a valid outcome. // Not generating en error message here as resolution failure is a valid outcome.
return std::nullopt; return nonstd::nullopt;
} }
if (address == "255.255.255.255"sv) if (address == "255.255.255.255")
{ {
// The broadcast address needs to be handled explicitly, // The broadcast address needs to be handled explicitly,
// because it is also the value returned by inet_addr on error // because it is also the value returned by inet_addr on error
return Broadcast; return Broadcast;
} }
if (address == "0.0.0.0"sv) if (address == "0.0.0.0")
return Any; return Any;
// Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx") // Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx")
if (const std::uint32_t ip = inet_addr(address.data()); ip != INADDR_NONE) const std::uint32_t ip = inet_addr(address.data());
if (ip != INADDR_NONE)
return IpAddress(ntohl(ip)); return IpAddress(ntohl(ip));
// Not a valid address, try to convert it as a host name // Not a valid address, try to convert it as a host name
@@ -87,7 +86,7 @@ std::optional<IpAddress> IpAddress::resolve(std::string_view address)
} }
// Not generating en error message here as resolution failure is a valid outcome. // Not generating en error message here as resolution failure is a valid outcome.
return std::nullopt; return nonstd::nullopt;
} }
@@ -122,7 +121,7 @@ std::uint32_t IpAddress::toInteger() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<IpAddress> IpAddress::getLocalAddress() nonstd::optional<IpAddress> IpAddress::getLocalAddress()
{ {
// The method here is to connect a UDP socket to a public ip, // The method here is to connect a UDP socket to a public ip,
// and get the local socket address with the getsockname function. // and get the local socket address with the getsockname function.
@@ -130,36 +129,36 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
// Create the socket // Create the socket
const SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0); const SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock == priv::SocketImpl::invalidSocket()) if (sock == SocketImpl::invalidSocket())
{ {
err() << "Failed to retrieve local address (invalid socket)" << std::endl; err() << "Failed to retrieve local address (invalid socket)" << std::endl;
return std::nullopt; return nonstd::nullopt;
} }
// Connect the socket to a public ip (here 1.1.1.1) on any // Connect the socket to a public ip (here 1.1.1.1) on any
// port. This will give the local address of the network interface // port. This will give the local address of the network interface
// used for default routing which is usually what we want. // used for default routing which is usually what we want.
sockaddr_in address = priv::SocketImpl::createAddress(0x01010101, 9); sockaddr_in address = SocketImpl::createAddress(0x01010101, 9);
if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1) if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
{ {
priv::SocketImpl::close(sock); SocketImpl::close(sock);
err() << "Failed to retrieve local address (socket connection failure)" << std::endl; err() << "Failed to retrieve local address (socket connection failure)" << std::endl;
return std::nullopt; return nonstd::nullopt;
} }
// Get the local address of the socket connection // Get the local address of the socket connection
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &size) == -1) if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &size) == -1)
{ {
priv::SocketImpl::close(sock); SocketImpl::close(sock);
err() << "Failed to retrieve local address (socket local address retrieval failure)" << std::endl; err() << "Failed to retrieve local address (socket local address retrieval failure)" << std::endl;
return std::nullopt; return nonstd::nullopt;
} }
// Close the socket // Close the socket
priv::SocketImpl::close(sock); SocketImpl::close(sock);
// Finally build the IP address // Finally build the IP address
return IpAddress(ntohl(address.sin_addr.s_addr)); return IpAddress(ntohl(address.sin_addr.s_addr));
@@ -167,7 +166,7 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<IpAddress> IpAddress::getPublicAddress(Time timeout) nonstd::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
{ {
// The trick here is more complicated, because the only way // The trick here is more complicated, because the only way
// to get our public IP address is to get it from a distant computer. // to get our public IP address is to get it from a distant computer.
@@ -187,7 +186,7 @@ std::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
err() << "Failed to retrieve public address from external IP resolution server (HTTP response status " err() << "Failed to retrieve public address from external IP resolution server (HTTP response status "
<< static_cast<int>(status) << ")" << std::endl; << static_cast<int>(status) << ")" << std::endl;
return std::nullopt; return nonstd::nullopt;
} }
@@ -234,7 +233,7 @@ bool operator>=(IpAddress left, IpAddress right)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::istream& operator>>(std::istream& stream, std::optional<IpAddress>& address) std::istream& operator>>(std::istream& stream, nonstd::optional<IpAddress>& address)
{ {
std::string str; std::string str;
stream >> str; stream >> str;

View File

@@ -45,7 +45,7 @@ void Packet::append(const void* data, std::size_t sizeInBytes)
{ {
if (data && (sizeInBytes > 0)) if (data && (sizeInBytes > 0))
{ {
const auto* begin = reinterpret_cast<const std::byte*>(data); const auto* begin = reinterpret_cast<const unsigned char*>(data);
const auto* end = begin + sizeInBytes; const auto* end = begin + sizeInBytes;
m_data.insert(m_data.end(), begin, end); m_data.insert(m_data.end(), begin, end);
} }
@@ -196,10 +196,10 @@ Packet& Packet::operator>>(std::int64_t& data)
{ {
// Since ntohll is not available everywhere, we have to convert // Since ntohll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
std::array<std::byte, sizeof(data)> bytes{}; std::array<unsigned char, sizeof(data)> bytes{};
std::memcpy(bytes.data(), &m_data[m_readPos], bytes.size()); std::memcpy(bytes.data(), &m_data[m_readPos], bytes.size());
data = toInteger<std::int64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]); data = toInteger<std::int64_t>(bytes);
m_readPos += sizeof(data); m_readPos += sizeof(data);
} }
@@ -215,10 +215,10 @@ Packet& Packet::operator>>(std::uint64_t& data)
{ {
// Since ntohll is not available everywhere, we have to convert // Since ntohll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
std::array<std::byte, sizeof(data)> bytes{}; std::array<unsigned char, sizeof(data)> bytes{};
std::memcpy(bytes.data(), &m_data[m_readPos], sizeof(data)); std::memcpy(bytes.data(), &m_data[m_readPos], sizeof(data));
data = toInteger<std::uint64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]); data = toInteger<std::uint64_t>(bytes);
m_readPos += sizeof(data); m_readPos += sizeof(data);
} }
@@ -434,7 +434,7 @@ Packet& Packet::operator<<(std::int64_t data)
// Since htonll is not available everywhere, we have to convert // Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF), const std::array<std::uint8_t,8> toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
static_cast<std::uint8_t>((data >> 48) & 0xFF), static_cast<std::uint8_t>((data >> 48) & 0xFF),
static_cast<std::uint8_t>((data >> 40) & 0xFF), static_cast<std::uint8_t>((data >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF), static_cast<std::uint8_t>((data >> 32) & 0xFF),
@@ -454,7 +454,7 @@ Packet& Packet::operator<<(std::uint64_t data)
// Since htonll is not available everywhere, we have to convert // Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF), const std::array<std::uint8_t,8> toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
static_cast<std::uint8_t>((data >> 48) & 0xFF), static_cast<std::uint8_t>((data >> 48) & 0xFF),
static_cast<std::uint8_t>((data >> 40) & 0xFF), static_cast<std::uint8_t>((data >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF), static_cast<std::uint8_t>((data >> 32) & 0xFF),

View File

@@ -37,7 +37,7 @@
namespace sf namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Socket::Socket(Type type) : m_type(type), m_socket(priv::SocketImpl::invalidSocket()) Socket::Socket(Type type) : m_type(type), m_socket(SocketImpl::invalidSocket())
{ {
} }
@@ -53,7 +53,7 @@ Socket::~Socket()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Socket::Socket(Socket&& socket) noexcept : Socket::Socket(Socket&& socket) noexcept :
m_type(socket.m_type), m_type(socket.m_type),
m_socket(std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket())), m_socket(std::exchange(socket.m_socket, SocketImpl::invalidSocket())),
m_isBlocking(socket.m_isBlocking) m_isBlocking(socket.m_isBlocking)
{ {
} }
@@ -68,7 +68,7 @@ Socket& Socket::operator=(Socket&& socket) noexcept
close(); close();
m_type = socket.m_type; m_type = socket.m_type;
m_socket = std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket()); m_socket = std::exchange(socket.m_socket, SocketImpl::invalidSocket());
m_isBlocking = socket.m_isBlocking; m_isBlocking = socket.m_isBlocking;
return *this; return *this;
} }
@@ -78,8 +78,8 @@ Socket& Socket::operator=(Socket&& socket) noexcept
void Socket::setBlocking(bool blocking) void Socket::setBlocking(bool blocking)
{ {
// Apply if the socket is already created // Apply if the socket is already created
if (m_socket != priv::SocketImpl::invalidSocket()) if (m_socket != SocketImpl::invalidSocket())
priv::SocketImpl::setBlocking(m_socket, blocking); SocketImpl::setBlocking(m_socket, blocking);
m_isBlocking = blocking; m_isBlocking = blocking;
} }
@@ -103,11 +103,11 @@ SocketHandle Socket::getNativeHandle() const
void Socket::create() void Socket::create()
{ {
// Don't create the socket if it already exists // Don't create the socket if it already exists
if (m_socket == priv::SocketImpl::invalidSocket()) if (m_socket == SocketImpl::invalidSocket())
{ {
const SocketHandle handle = socket(PF_INET, m_type == Type::Tcp ? SOCK_STREAM : SOCK_DGRAM, 0); const SocketHandle handle = socket(PF_INET, m_type == Type::Tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
if (handle == priv::SocketImpl::invalidSocket()) if (handle == SocketImpl::invalidSocket())
{ {
err() << "Failed to create socket" << std::endl; err() << "Failed to create socket" << std::endl;
return; return;
@@ -122,7 +122,7 @@ void Socket::create()
void Socket::create(SocketHandle handle) void Socket::create(SocketHandle handle)
{ {
// Don't create the socket if it already exists // Don't create the socket if it already exists
if (m_socket == priv::SocketImpl::invalidSocket()) if (m_socket == SocketImpl::invalidSocket())
{ {
// Assign the new handle // Assign the new handle
m_socket = handle; m_socket = handle;
@@ -165,10 +165,10 @@ void Socket::create(SocketHandle handle)
void Socket::close() void Socket::close()
{ {
// Close the socket // Close the socket
if (m_socket != priv::SocketImpl::invalidSocket()) if (m_socket != SocketImpl::invalidSocket())
{ {
priv::SocketImpl::close(m_socket); SocketImpl::close(m_socket);
m_socket = priv::SocketImpl::invalidSocket(); m_socket = SocketImpl::invalidSocket();
} }
} }

View File

@@ -54,7 +54,7 @@
#include <cstdint> #include <cstdint>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Helper class implementing all the non-portable /// \brief Helper class implementing all the non-portable
@@ -120,4 +120,4 @@ public:
static Socket::Status getErrorStatus(); static Socket::Status getErrorStatus();
}; };
} // namespace sf::priv } // namespace sf

View File

@@ -91,7 +91,7 @@ SocketSelector& SocketSelector::operator=(SocketSelector&&) noexcept = default;
void SocketSelector::add(Socket& socket) void SocketSelector::add(Socket& socket)
{ {
const SocketHandle handle = socket.getNativeHandle(); const SocketHandle handle = socket.getNativeHandle();
if (handle != priv::SocketImpl::invalidSocket()) if (handle != SocketImpl::invalidSocket())
{ {
#if defined(SFML_SYSTEM_WINDOWS) #if defined(SFML_SYSTEM_WINDOWS)
@@ -133,7 +133,7 @@ void SocketSelector::add(Socket& socket)
void SocketSelector::remove(Socket& socket) void SocketSelector::remove(Socket& socket)
{ {
const SocketHandle handle = socket.getNativeHandle(); const SocketHandle handle = socket.getNativeHandle();
if (handle != priv::SocketImpl::invalidSocket()) if (handle != SocketImpl::invalidSocket())
{ {
#if defined(SFML_SYSTEM_WINDOWS) #if defined(SFML_SYSTEM_WINDOWS)
@@ -190,7 +190,7 @@ bool SocketSelector::wait(Time timeout)
bool SocketSelector::isReady(Socket& socket) const bool SocketSelector::isReady(Socket& socket) const
{ {
const SocketHandle handle = socket.getNativeHandle(); const SocketHandle handle = socket.getNativeHandle();
if (handle != priv::SocketImpl::invalidSocket()) if (handle != SocketImpl::invalidSocket())
{ {
#if !defined(SFML_SYSTEM_WINDOWS) #if !defined(SFML_SYSTEM_WINDOWS)

View File

@@ -45,11 +45,11 @@ TcpListener::TcpListener() : Socket(Type::Tcp)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned short TcpListener::getLocalPort() const unsigned short TcpListener::getLocalPort() const
{ {
if (getNativeHandle() != priv::SocketImpl::invalidSocket()) if (getNativeHandle() != SocketImpl::invalidSocket())
{ {
// Retrieve information about the local end of the socket // Retrieve information about the local end of the socket
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1) if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
{ {
return ntohs(address.sin_port); return ntohs(address.sin_port);
@@ -75,7 +75,7 @@ Socket::Status TcpListener::listen(unsigned short port, IpAddress address)
return Status::Error; return Status::Error;
// Bind the socket to the specified port // Bind the socket to the specified port
sockaddr_in addr = priv::SocketImpl::createAddress(address.toInteger(), port); sockaddr_in addr = SocketImpl::createAddress(address.toInteger(), port);
if (bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) if (bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
{ {
// Not likely to happen, but... // Not likely to happen, but...
@@ -107,7 +107,7 @@ void TcpListener::close()
Socket::Status TcpListener::accept(TcpSocket& socket) Socket::Status TcpListener::accept(TcpSocket& socket)
{ {
// Make sure that we're listening // Make sure that we're listening
if (getNativeHandle() == priv::SocketImpl::invalidSocket()) if (getNativeHandle() == SocketImpl::invalidSocket())
{ {
err() << "Failed to accept a new connection, the socket is not listening" << std::endl; err() << "Failed to accept a new connection, the socket is not listening" << std::endl;
return Status::Error; return Status::Error;
@@ -115,12 +115,12 @@ Socket::Status TcpListener::accept(TcpSocket& socket)
// Accept a new connection // Accept a new connection
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength length = sizeof(address); SocketImpl::AddrLength length = sizeof(address);
const SocketHandle remote = ::accept(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &length); const SocketHandle remote = ::accept(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &length);
// Check for errors // Check for errors
if (remote == priv::SocketImpl::invalidSocket()) if (remote == SocketImpl::invalidSocket())
return priv::SocketImpl::getErrorStatus(); return SocketImpl::getErrorStatus();
// Initialize the new connected socket // Initialize the new connected socket
socket.close(); socket.close();

View File

@@ -64,11 +64,11 @@ TcpSocket::TcpSocket() : Socket(Type::Tcp)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned short TcpSocket::getLocalPort() const unsigned short TcpSocket::getLocalPort() const
{ {
if (getNativeHandle() != priv::SocketImpl::invalidSocket()) if (getNativeHandle() != SocketImpl::invalidSocket())
{ {
// Retrieve information about the local end of the socket // Retrieve information about the local end of the socket
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1) if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
{ {
return ntohs(address.sin_port); return ntohs(address.sin_port);
@@ -81,13 +81,13 @@ unsigned short TcpSocket::getLocalPort() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<IpAddress> TcpSocket::getRemoteAddress() const nonstd::optional<IpAddress> TcpSocket::getRemoteAddress() const
{ {
if (getNativeHandle() != priv::SocketImpl::invalidSocket()) if (getNativeHandle() != SocketImpl::invalidSocket())
{ {
// Retrieve information about the remote end of the socket // Retrieve information about the remote end of the socket
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1) if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
{ {
return IpAddress(ntohl(address.sin_addr.s_addr)); return IpAddress(ntohl(address.sin_addr.s_addr));
@@ -95,18 +95,18 @@ std::optional<IpAddress> TcpSocket::getRemoteAddress() const
} }
// We failed to retrieve the address // We failed to retrieve the address
return std::nullopt; return nonstd::nullopt;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned short TcpSocket::getRemotePort() const unsigned short TcpSocket::getRemotePort() const
{ {
if (getNativeHandle() != priv::SocketImpl::invalidSocket()) if (getNativeHandle() != SocketImpl::invalidSocket())
{ {
// Retrieve information about the remote end of the socket // Retrieve information about the remote end of the socket
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1) if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
{ {
return ntohs(address.sin_port); return ntohs(address.sin_port);
@@ -128,7 +128,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
create(); create();
// Create the remote address // Create the remote address
sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort); sockaddr_in address = SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
if (timeout <= Time::Zero) if (timeout <= Time::Zero)
{ {
@@ -136,7 +136,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
// Connect the socket // Connect the socket
if (::connect(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1) if (::connect(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
return priv::SocketImpl::getErrorStatus(); return SocketImpl::getErrorStatus();
// Connection succeeded // Connection succeeded
return Status::Done; return Status::Done;
@@ -160,7 +160,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
} }
// Get the error status // Get the error status
Status status = priv::SocketImpl::getErrorStatus(); Status status = SocketImpl::getErrorStatus();
// If we were in non-blocking mode, return immediately // If we were in non-blocking mode, return immediately
if (!blocking) if (!blocking)
@@ -192,13 +192,13 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
else else
{ {
// Connection refused // Connection refused
status = priv::SocketImpl::getErrorStatus(); status = SocketImpl::getErrorStatus();
} }
} }
else else
{ {
// Failed to connect before timeout is over // Failed to connect before timeout is over
status = priv::SocketImpl::getErrorStatus(); status = SocketImpl::getErrorStatus();
} }
} }
@@ -251,14 +251,14 @@ Socket::Status TcpSocket::send(const void* data, std::size_t size, std::size_t&
// Send a chunk of data // Send a chunk of data
result = static_cast<int>(::send(getNativeHandle(), result = static_cast<int>(::send(getNativeHandle(),
static_cast<const char*>(data) + sent, static_cast<const char*>(data) + sent,
static_cast<priv::SocketImpl::Size>(size - sent), static_cast<SocketImpl::Size>(size - sent),
flags)); flags));
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
// Check for errors // Check for errors
if (result < 0) if (result < 0)
{ {
const Status status = priv::SocketImpl::getErrorStatus(); const Status status = SocketImpl::getErrorStatus();
if ((status == Status::NotReady) && sent) if ((status == Status::NotReady) && sent)
return Status::Partial; return Status::Partial;
@@ -288,7 +288,7 @@ Socket::Status TcpSocket::receive(void* data, std::size_t size, std::size_t& rec
#pragma GCC diagnostic ignored "-Wuseless-cast" #pragma GCC diagnostic ignored "-Wuseless-cast"
// Receive a chunk of bytes // Receive a chunk of bytes
const int sizeReceived = static_cast<int>( const int sizeReceived = static_cast<int>(
recv(getNativeHandle(), static_cast<char*>(data), static_cast<priv::SocketImpl::Size>(size), flags)); recv(getNativeHandle(), static_cast<char*>(data), static_cast<SocketImpl::Size>(size), flags));
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
// Check the number of bytes received // Check the number of bytes received
@@ -302,7 +302,7 @@ Socket::Status TcpSocket::receive(void* data, std::size_t size, std::size_t& rec
return Socket::Status::Disconnected; return Socket::Status::Disconnected;
} }
return priv::SocketImpl::getErrorStatus(); return SocketImpl::getErrorStatus();
} }
@@ -346,7 +346,7 @@ Socket::Status TcpSocket::send(Packet& packet)
// Send the data block // Send the data block
std::size_t sent = 0; std::size_t sent = 0;
const Status status = send(m_blockToSendBuffer.data() + packet.m_sendPos, const Status status = send(m_blockToSendBuffer.data() + packet.m_sendPos,
static_cast<priv::SocketImpl::Size>(m_blockToSendBuffer.size() - packet.m_sendPos), static_cast<SocketImpl::Size>(m_blockToSendBuffer.size() - packet.m_sendPos),
sent); sent);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
@@ -411,7 +411,7 @@ Socket::Status TcpSocket::receive(Packet& packet)
if (received > 0) if (received > 0)
{ {
m_pendingPacket.data.resize(m_pendingPacket.data.size() + received); m_pendingPacket.data.resize(m_pendingPacket.data.size() + received);
std::byte* begin = m_pendingPacket.data.data() + m_pendingPacket.data.size() - received; unsigned char* begin = m_pendingPacket.data.data() + m_pendingPacket.data.size() - received;
std::memcpy(begin, buffer.data(), received); std::memcpy(begin, buffer.data(), received);
} }
} }

View File

@@ -42,17 +42,18 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
UdpSocket::UdpSocket() : Socket(Type::Udp) UdpSocket::UdpSocket() : Socket(Type::Udp)
{ {
m_buffer.reserve(MaxDatagramSize);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned short UdpSocket::getLocalPort() const unsigned short UdpSocket::getLocalPort() const
{ {
if (getNativeHandle() != priv::SocketImpl::invalidSocket()) if (getNativeHandle() != SocketImpl::invalidSocket())
{ {
// Retrieve information about the local end of the socket // Retrieve information about the local end of the socket
sockaddr_in address{}; sockaddr_in address{};
priv::SocketImpl::AddrLength size = sizeof(address); SocketImpl::AddrLength size = sizeof(address);
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1) if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
{ {
return ntohs(address.sin_port); return ntohs(address.sin_port);
@@ -78,7 +79,7 @@ Socket::Status UdpSocket::bind(unsigned short port, IpAddress address)
return Status::Error; return Status::Error;
// Bind the socket // Bind the socket
sockaddr_in addr = priv::SocketImpl::createAddress(address.toInteger(), port); sockaddr_in addr = SocketImpl::createAddress(address.toInteger(), port);
if (::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) if (::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
{ {
err() << "Failed to bind socket to port " << port << std::endl; err() << "Failed to bind socket to port " << port << std::endl;
@@ -107,12 +108,12 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
if (size > MaxDatagramSize) if (size > MaxDatagramSize)
{ {
err() << "Cannot send data over the network " err() << "Cannot send data over the network "
<< "(the number of bytes to send is greater than sf::UdpSocket::MaxDatagramSize)" << std::endl; << "(the number of bytes to send is greater than UdpSocket::MaxDatagramSize)" << std::endl;
return Status::Error; return Status::Error;
} }
// Build the target address // Build the target address
sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort); sockaddr_in address = SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuseless-cast" #pragma GCC diagnostic ignored "-Wuseless-cast"
@@ -120,7 +121,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
const int sent = static_cast<int>( const int sent = static_cast<int>(
sendto(getNativeHandle(), sendto(getNativeHandle(),
static_cast<const char*>(data), static_cast<const char*>(data),
static_cast<priv::SocketImpl::Size>(size), static_cast<SocketImpl::Size>(size),
0, 0,
reinterpret_cast<sockaddr*>(&address), reinterpret_cast<sockaddr*>(&address),
sizeof(address))); sizeof(address)));
@@ -128,7 +129,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
// Check for errors // Check for errors
if (sent < 0) if (sent < 0)
return priv::SocketImpl::getErrorStatus(); return SocketImpl::getErrorStatus();
return Status::Done; return Status::Done;
} }
@@ -138,12 +139,12 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
Socket::Status UdpSocket::receive(void* data, Socket::Status UdpSocket::receive(void* data,
std::size_t size, std::size_t size,
std::size_t& received, std::size_t& received,
std::optional<IpAddress>& remoteAddress, nonstd::optional<IpAddress>& remoteAddress,
unsigned short& remotePort) unsigned short& remotePort)
{ {
// First clear the variables to fill // First clear the variables to fill
received = 0; received = 0;
remoteAddress = std::nullopt; remoteAddress = nonstd::nullopt;
remotePort = 0; remotePort = 0;
// Check the destination buffer // Check the destination buffer
@@ -154,16 +155,16 @@ Socket::Status UdpSocket::receive(void* data,
} }
// Data that will be filled with the other computer's address // Data that will be filled with the other computer's address
sockaddr_in address = priv::SocketImpl::createAddress(INADDR_ANY, 0); sockaddr_in address = SocketImpl::createAddress(INADDR_ANY, 0);
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuseless-cast" #pragma GCC diagnostic ignored "-Wuseless-cast"
// Receive a chunk of bytes // Receive a chunk of bytes
priv::SocketImpl::AddrLength addressSize = sizeof(address); SocketImpl::AddrLength addressSize = sizeof(address);
const int sizeReceived = static_cast<int>( const int sizeReceived = static_cast<int>(
recvfrom(getNativeHandle(), recvfrom(getNativeHandle(),
static_cast<char*>(data), static_cast<char*>(data),
static_cast<priv::SocketImpl::Size>(size), static_cast<SocketImpl::Size>(size),
0, 0,
reinterpret_cast<sockaddr*>(&address), reinterpret_cast<sockaddr*>(&address),
&addressSize)); &addressSize));
@@ -171,7 +172,7 @@ Socket::Status UdpSocket::receive(void* data,
// Check for errors // Check for errors
if (sizeReceived < 0) if (sizeReceived < 0)
return priv::SocketImpl::getErrorStatus(); return SocketImpl::getErrorStatus();
// Fill the sender information // Fill the sender information
received = static_cast<std::size_t>(sizeReceived); received = static_cast<std::size_t>(sizeReceived);
@@ -203,7 +204,7 @@ Socket::Status UdpSocket::send(Packet& packet, IpAddress remoteAddress, unsigned
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Socket::Status UdpSocket::receive(Packet& packet, std::optional<IpAddress>& remoteAddress, unsigned short& remotePort) Socket::Status UdpSocket::receive(Packet& packet, nonstd::optional<IpAddress>& remoteAddress, unsigned short& remotePort)
{ {
// See the detailed comment in send(Packet) above. // See the detailed comment in send(Packet) above.

View File

@@ -35,7 +35,7 @@
#include <cerrno> #include <cerrno>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port) sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
@@ -108,4 +108,4 @@ Socket::Status SocketImpl::getErrorStatus()
// clang-format on // clang-format on
} }
} // namespace sf::priv } // namespace sf

View File

@@ -53,7 +53,7 @@ struct SocketInitializer
} // namespace } // namespace
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port) sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
@@ -107,4 +107,4 @@ Socket::Status SocketImpl::getErrorStatus()
} }
// clang-format on // clang-format on
} }
} // namespace sf::priv } // namespace sf

View File

@@ -49,7 +49,7 @@ std::streambuf::int_type LogcatStream::overflow(std::streambuf::int_type c)
return traits_type::not_eof(c); return traits_type::not_eof(c);
} }
namespace sf::priv namespace sf
{ {
ActivityStates*& getActivityStatesPtr() ActivityStates*& getActivityStatesPtr()
@@ -67,8 +67,8 @@ ActivityStates& getActivity()
{ {
ActivityStates* const states = getActivityStatesPtr(); ActivityStates* const states = getActivityStatesPtr();
assert(states != nullptr && assert(states != nullptr &&
"Cannot dereference null activity states pointer. Call priv::resetActivity() to initialize it."); "Cannot dereference null activity states pointer. Call resetActivity() to initialize it.");
return *states; return *states;
} }
} // namespace sf::priv } // namespace sf

View File

@@ -54,7 +54,7 @@ private:
std::string m_message; std::string m_message;
}; };
namespace sf::priv namespace sf
{ {
struct ActivityStates struct ActivityStates
{ {
@@ -68,7 +68,7 @@ struct ActivityStates
EGLDisplay display{}; EGLDisplay display{};
EglContext* context{}; EglContext* context{};
std::vector<std::byte> savedState; std::vector<unsigned char> savedState;
std::recursive_mutex mutex; std::recursive_mutex mutex;
@@ -100,4 +100,4 @@ SFML_SYSTEM_API void resetActivity(ActivityStates* initializedStates);
SFML_SYSTEM_API ActivityStates& getActivity(); SFML_SYSTEM_API ActivityStates& getActivity();
} // namespace sf::priv } // namespace sf

View File

@@ -33,7 +33,7 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ANativeActivity* getNativeActivity() ANativeActivity* getNativeActivity()
{ {
return priv::getActivity().activity; return getActivity().activity;
} }
} // namespace sf } // namespace sf

View File

@@ -32,10 +32,10 @@
#include <mutex> #include <mutex>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool ResourceStream::open(const std::filesystem::path& filename) bool ResourceStream::open(const ghc::filesystem::path& filename)
{ {
ActivityStates& states = getActivity(); ActivityStates& states = getActivity();
const std::lock_guard lock(states.mutex); const std::lock_guard lock(states.mutex);
@@ -45,29 +45,29 @@ bool ResourceStream::open(const std::filesystem::path& filename)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> ResourceStream::read(void* data, std::size_t size) nonstd::optional<std::size_t> ResourceStream::read(void* data, std::size_t size)
{ {
assert(m_file && "ResourceStream::read() cannot be called when file is not initialized"); assert(m_file && "ResourceStream::read() cannot be called when file is not initialized");
const auto numBytesRead = AAsset_read(m_file.get(), data, size); const auto numBytesRead = AAsset_read(m_file.get(), data, size);
if (numBytesRead < 0) if (numBytesRead < 0)
return std::nullopt; return nonstd::nullopt;
return numBytesRead; return numBytesRead;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> ResourceStream::seek(std::size_t position) nonstd::optional<std::size_t> ResourceStream::seek(std::size_t position)
{ {
assert(m_file && "ResourceStream::seek() cannot be called when file is not initialized"); assert(m_file && "ResourceStream::seek() cannot be called when file is not initialized");
const auto newPosition = AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET); const auto newPosition = AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET);
if (newPosition < 0) if (newPosition < 0)
return std::nullopt; return nonstd::nullopt;
return newPosition; return newPosition;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> ResourceStream::tell() nonstd::optional<std::size_t> ResourceStream::tell()
{ {
assert(m_file && "ResourceStream::tell() cannot be called when file is not initialized"); assert(m_file && "ResourceStream::tell() cannot be called when file is not initialized");
return getSize().value() - static_cast<std::size_t>(AAsset_getRemainingLength(m_file.get())); return getSize().value() - static_cast<std::size_t>(AAsset_getRemainingLength(m_file.get()));
@@ -75,7 +75,7 @@ std::optional<std::size_t> ResourceStream::tell()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> ResourceStream::getSize() nonstd::optional<std::size_t> ResourceStream::getSize()
{ {
assert(m_file && "ResourceStream::getSize() cannot be called when file is not initialized"); assert(m_file && "ResourceStream::getSize() cannot be called when file is not initialized");
return AAsset_getLength(m_file.get()); return AAsset_getLength(m_file.get());
@@ -88,4 +88,4 @@ void ResourceStream::AAssetDeleter::operator()(AAsset* file)
AAsset_close(file); AAsset_close(file);
} }
} // namespace sf::priv } // namespace sf

View File

@@ -33,11 +33,11 @@
#include <android/asset_manager.h> #include <android/asset_manager.h>
#include <filesystem> #include "filesystem.hpp"
#include <string> #include <string>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Read from Android asset files /// \brief Read from Android asset files
@@ -62,7 +62,7 @@ public:
/// \return `true` on success, `false` on error /// \return `true` on success, `false` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool open(const std::filesystem::path& filename); [[nodiscard]] bool open(const ghc::filesystem::path& filename);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Read data from the asset /// \brief Read data from the asset
@@ -70,36 +70,36 @@ public:
/// \param data Buffer where the asset data is copied /// \param data Buffer where the asset data is copied
/// \param size Number of bytes read /// \param size Number of bytes read
/// ///
/// \return The number of bytes actually read, or `std::nullopt` on error /// \return The number of bytes actually read, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> read(void* data, std::size_t size) override; nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Change the current reading position in the asset file /// \brief Change the current reading position in the asset file
/// ///
/// \param position The position to seek to, from the beginning /// \param position The position to seek to, from the beginning
/// ///
/// \return The position actually sought to, or `std::nullopt` on error /// \return The position actually sought to, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> seek(std::size_t position) override; nonstd::optional<std::size_t> seek(std::size_t position) override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the current reading position in the asset file /// \brief Get the current reading position in the asset file
/// ///
/// \return The current position, or `std::nullopt` on error. /// \return The current position, or `nonstd::nullopt` on error.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> tell() override; nonstd::optional<std::size_t> tell() override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the size of the asset file /// \brief Return the size of the asset file
/// ///
/// \return The total number of bytes available in the asset, or `std::nullopt` on error /// \return The total number of bytes available in the asset, or `nonstd::nullopt` on error
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> getSize() override; nonstd::optional<std::size_t> getSize() override;
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@@ -116,4 +116,4 @@ private:
std::unique_ptr<AAsset, AAssetDeleter> m_file; ///< The asset file to read std::unique_ptr<AAsset, AAssetDeleter> m_file; ///< The asset file to read
}; };
} // namespace sf::priv } // namespace sf

View File

@@ -5,6 +5,7 @@ set(SRCROOT ${PROJECT_SOURCE_DIR}/src/SFML/System)
# all source files # all source files
set(SRC set(SRC
${INCROOT}/../System.hpp
${INCROOT}/Angle.hpp ${INCROOT}/Angle.hpp
${INCROOT}/Angle.inl ${INCROOT}/Angle.inl
${INCROOT}/Clock.hpp ${INCROOT}/Clock.hpp
@@ -72,9 +73,10 @@ endif()
# define the sfml-system target # define the sfml-system target
add_library(sfml-system STATIC ${SRC} ${PLATFORM_SRC}) add_library(sfml-system STATIC ${SRC} ${PLATFORM_SRC})
target_include_directories(sfml-system PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR}/../../../include) target_include_directories(sfml-system PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR}/../../../include ${NONSTD_INCLUDE_DIR})
target_compile_definitions(sfml-system PRIVATE SFML_STATIC) target_compile_definitions(sfml-system PRIVATE SFML_STATIC)
target_compile_definitions(sfml-system INTERFACE SFML_STATIC)
if(ANDROID) if(ANDROID)
# glad sources # glad sources
@@ -85,7 +87,7 @@ endif()
if(UNIX OR APPLE) if(UNIX OR APPLE)
target_link_libraries(sfml-system PRIVATE pthread) target_link_libraries(sfml-system PRIVATE pthread)
endif() endif()
if(UNIX) if(UNIX AND NOT APPLE)
target_link_libraries(sfml-system PRIVATE rt) target_link_libraries(sfml-system PRIVATE rt)
elseif(WIN32) elseif(WIN32)
target_link_libraries(sfml-system PRIVATE winmm) target_link_libraries(sfml-system PRIVATE winmm)

View File

@@ -35,7 +35,7 @@ namespace sf
Time Clock::getElapsedTime() const Time Clock::getElapsedTime() const
{ {
if (isRunning()) if (isRunning())
return std::chrono::duration_cast<std::chrono::microseconds>(priv::ClockImpl::now() - m_refPoint); return std::chrono::duration_cast<std::chrono::microseconds>(ClockImpl::now() - m_refPoint);
return std::chrono::duration_cast<std::chrono::microseconds>(m_stopPoint - m_refPoint); return std::chrono::duration_cast<std::chrono::microseconds>(m_stopPoint - m_refPoint);
} }
@@ -43,7 +43,7 @@ Time Clock::getElapsedTime() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Clock::isRunning() const bool Clock::isRunning() const
{ {
return m_stopPoint == priv::ClockImpl::time_point(); return m_stopPoint == ClockImpl::time_point();
} }
@@ -52,7 +52,7 @@ void Clock::start()
{ {
if (!isRunning()) if (!isRunning())
{ {
m_refPoint += priv::ClockImpl::now() - m_stopPoint; m_refPoint += ClockImpl::now() - m_stopPoint;
m_stopPoint = {}; m_stopPoint = {};
} }
} }
@@ -62,7 +62,7 @@ void Clock::start()
void Clock::stop() void Clock::stop()
{ {
if (isRunning()) if (isRunning())
m_stopPoint = priv::ClockImpl::now(); m_stopPoint = ClockImpl::now();
} }
@@ -70,7 +70,7 @@ void Clock::stop()
Time Clock::restart() Time Clock::restart()
{ {
const Time elapsed = getElapsedTime(); const Time elapsed = getElapsedTime();
m_refPoint = priv::ClockImpl::now(); m_refPoint = ClockImpl::now();
m_stopPoint = {}; m_stopPoint = {};
return elapsed; return elapsed;
} }
@@ -80,7 +80,7 @@ Time Clock::restart()
Time Clock::reset() Time Clock::reset()
{ {
const Time elapsed = getElapsedTime(); const Time elapsed = getElapsedTime();
m_refPoint = priv::ClockImpl::now(); m_refPoint = ClockImpl::now();
m_stopPoint = m_refPoint; m_stopPoint = m_refPoint;
return elapsed; return elapsed;
} }

View File

@@ -34,7 +34,7 @@
#include <cstddef> #include <cstddef>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Fixed-size array container indexed by an enumeration /// \brief Fixed-size array container indexed by an enumeration
@@ -72,4 +72,4 @@ struct EnumArray : public std::array<Value, Count>
} }
}; };
} // namespace sf::priv } // namespace sf

View File

@@ -35,7 +35,7 @@
namespace namespace
{ {
// This class will be used as the default streambuf of sf::Err, // This class will be used as the default streambuf of Err,
// it outputs to stderr by default (to keep the default behavior) // it outputs to stderr by default (to keep the default behavior)
class DefaultErrStreamBuf : public std::streambuf class DefaultErrStreamBuf : public std::streambuf
{ {

View File

@@ -50,7 +50,7 @@ FileInputStream::FileInputStream() = default;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
FileInputStream::FileInputStream(const std::filesystem::path& filename) FileInputStream::FileInputStream(const ghc::filesystem::path& filename)
{ {
if (!open(filename)) if (!open(filename))
throw Exception("Failed to open file input stream"); throw Exception("Failed to open file input stream");
@@ -70,12 +70,12 @@ FileInputStream& FileInputStream::operator=(FileInputStream&&) noexcept = defaul
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool FileInputStream::open(const std::filesystem::path& filename) bool FileInputStream::open(const ghc::filesystem::path& filename)
{ {
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
if (priv::getActivityStatesPtr() != nullptr) if (getActivityStatesPtr() != nullptr)
{ {
m_androidFile = std::make_unique<priv::ResourceStream>(); m_androidFile = std::make_unique<ResourceStream>();
if (!m_androidFile->open(filename)) if (!m_androidFile->open(filename))
return false; return false;
return m_androidFile->tell().has_value(); return m_androidFile->tell().has_value();
@@ -87,79 +87,79 @@ bool FileInputStream::open(const std::filesystem::path& filename)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> FileInputStream::read(void* data, std::size_t size) nonstd::optional<std::size_t> FileInputStream::read(void* data, std::size_t size)
{ {
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
if (priv::getActivityStatesPtr() != nullptr) if (getActivityStatesPtr() != nullptr)
{ {
if (!m_androidFile) if (!m_androidFile)
return std::nullopt; return nonstd::nullopt;
return m_androidFile->read(data, size); return m_androidFile->read(data, size);
} }
#endif #endif
if (!m_file) if (!m_file)
return std::nullopt; return nonstd::nullopt;
return std::fread(data, 1, size, m_file.get()); return std::fread(data, 1, size, m_file.get());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> FileInputStream::seek(std::size_t position) nonstd::optional<std::size_t> FileInputStream::seek(std::size_t position)
{ {
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
if (priv::getActivityStatesPtr() != nullptr) if (getActivityStatesPtr() != nullptr)
{ {
if (!m_androidFile) if (!m_androidFile)
return std::nullopt; return nonstd::nullopt;
return m_androidFile->seek(position); return m_androidFile->seek(position);
} }
#endif #endif
if (!m_file) if (!m_file)
return std::nullopt; return nonstd::nullopt;
if (std::fseek(m_file.get(), static_cast<long>(position), SEEK_SET)) if (std::fseek(m_file.get(), static_cast<long>(position), SEEK_SET))
return std::nullopt; return nonstd::nullopt;
return tell(); return tell();
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> FileInputStream::tell() nonstd::optional<std::size_t> FileInputStream::tell()
{ {
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
if (priv::getActivityStatesPtr() != nullptr) if (getActivityStatesPtr() != nullptr)
{ {
if (!m_androidFile) if (!m_androidFile)
return std::nullopt; return nonstd::nullopt;
return m_androidFile->tell(); return m_androidFile->tell();
} }
#endif #endif
if (!m_file) if (!m_file)
return std::nullopt; return nonstd::nullopt;
const auto position = std::ftell(m_file.get()); const auto position = std::ftell(m_file.get());
return position < 0 ? std::nullopt : std::optional<std::size_t>(position); return position < 0 ? nonstd::nullopt : nonstd::optional<std::size_t>(position);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> FileInputStream::getSize() nonstd::optional<std::size_t> FileInputStream::getSize()
{ {
#ifdef SFML_SYSTEM_ANDROID #ifdef SFML_SYSTEM_ANDROID
if (priv::getActivityStatesPtr() != nullptr) if (getActivityStatesPtr() != nullptr)
{ {
if (!m_androidFile) if (!m_androidFile)
return std::nullopt; return nonstd::nullopt;
return m_androidFile->getSize(); return m_androidFile->getSize();
} }
#endif #endif
if (!m_file) if (!m_file)
return std::nullopt; return nonstd::nullopt;
const auto position = tell().value(); const auto position = tell().value();
std::fseek(m_file.get(), 0, SEEK_END); std::fseek(m_file.get(), 0, SEEK_END);
const std::optional size = tell(); const nonstd::optional<size_t> size = tell();
if (!seek(position).has_value()) if (!seek(position).has_value())
return std::nullopt; return nonstd::nullopt;
return size; return size;
} }

View File

@@ -36,17 +36,17 @@ namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
MemoryInputStream::MemoryInputStream(const void* data, std::size_t sizeInBytes) : MemoryInputStream::MemoryInputStream(const void* data, std::size_t sizeInBytes) :
m_data(static_cast<const std::byte*>(data)), m_data(static_cast<const unsigned char*>(data)),
m_size(sizeInBytes) m_size(sizeInBytes)
{ {
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size) nonstd::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
{ {
if (!m_data) if (!m_data)
return std::nullopt; return nonstd::nullopt;
const std::size_t count = std::min(size, m_size - m_offset); const std::size_t count = std::min(size, m_size - m_offset);
if (count > 0) if (count > 0)
@@ -60,10 +60,10 @@ std::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> MemoryInputStream::seek(std::size_t position) nonstd::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
{ {
if (!m_data) if (!m_data)
return std::nullopt; return nonstd::nullopt;
m_offset = position < m_size ? position : m_size; m_offset = position < m_size ? position : m_size;
return m_offset; return m_offset;
@@ -71,20 +71,20 @@ std::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> MemoryInputStream::tell() nonstd::optional<std::size_t> MemoryInputStream::tell()
{ {
if (!m_data) if (!m_data)
return std::nullopt; return nonstd::nullopt;
return m_offset; return m_offset;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::optional<std::size_t> MemoryInputStream::getSize() nonstd::optional<std::size_t> MemoryInputStream::getSize()
{ {
if (!m_data) if (!m_data)
return std::nullopt; return nonstd::nullopt;
return m_size; return m_size;
} }

View File

@@ -44,7 +44,7 @@ void sleep(Time duration)
// as it results in inconsistent sleeping times under MinGW-w64. // as it results in inconsistent sleeping times under MinGW-w64.
if (duration >= Time::Zero) if (duration >= Time::Zero)
priv::sleepImpl(duration); sleepImpl(duration);
} }
} // namespace sf } // namespace sf

View File

@@ -32,7 +32,7 @@
#include <ctime> #include <ctime>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sleepImpl(Time time) void sleepImpl(Time time)
@@ -54,4 +54,4 @@ void sleepImpl(Time time)
} }
} }
} // namespace sf::priv } // namespace sf

View File

@@ -35,14 +35,14 @@ namespace sf
class Time; class Time;
} }
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Unix implementation of sf::Sleep /// \brief Unix implementation of Sleep
/// ///
/// \param time Time to sleep /// \param time Time to sleep
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sleepImpl(Time time); void sleepImpl(Time time);
} // namespace sf::priv } // namespace sf

View File

@@ -41,17 +41,17 @@ std::string toLower(std::string str)
return str; return str;
} }
std::string formatDebugPathInfo(const std::filesystem::path& path) std::string formatDebugPathInfo(const ghc::filesystem::path& path)
{ {
std::ostringstream oss; std::ostringstream oss;
// convert to UTF-8 to handle non-ascii/non-latin1 filenames on windows // convert to UTF-8 to handle non-ascii/non-latin1 filenames on windows
// cast is required to work in C++20 where u8string is char8_t which can't be printed to char stream // cast is required to work in C++20 where u8string is char8_t which can't be printed to char stream
oss << " Provided path: " << reinterpret_cast<const char*>(path.u8string().c_str()) << '\n' // oss << " Provided path: " << reinterpret_cast<const char*>(path.u8string().c_str()) << '\n' //
<< " Absolute path: " << reinterpret_cast<const char*>(std::filesystem::absolute(path).u8string().c_str()); << " Absolute path: " << reinterpret_cast<const char*>(ghc::filesystem::absolute(path).u8string().c_str());
return oss.str(); return oss.str();
} }
std::FILE* openFile(const std::filesystem::path& filename, std::string_view mode) std::FILE* openFile(const ghc::filesystem::path& filename, std::string mode)
{ {
#ifdef SFML_SYSTEM_WINDOWS #ifdef SFML_SYSTEM_WINDOWS
const std::wstring wmode(mode.begin(), mode.end()); const std::wstring wmode(mode.begin(), mode.end());

View File

@@ -29,9 +29,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Export.hpp> #include <SFML/System/Export.hpp>
#include <filesystem> #include "filesystem.hpp"
#include <string> #include <string>
#include <string_view>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
@@ -40,19 +39,22 @@
namespace sf namespace sf
{ {
[[nodiscard]] SFML_SYSTEM_API std::string toLower(std::string str); [[nodiscard]] SFML_SYSTEM_API std::string toLower(std::string str);
[[nodiscard]] SFML_SYSTEM_API std::string formatDebugPathInfo(const std::filesystem::path& path); [[nodiscard]] SFML_SYSTEM_API std::string formatDebugPathInfo(const ghc::filesystem::path& path);
// Convert byte sequence into integer // Convert byte sequence into integer
// toInteger<int>(0x12, 0x34, 0x56) == 0x563412 // toInteger<int>(0x12, 0x34, 0x56) == 0x563412
template <typename IntegerType, typename... Bytes> template <typename IntegerType>
[[nodiscard]] constexpr IntegerType toInteger(Bytes... byte) [[nodiscard]] constexpr IntegerType toInteger(std::array<unsigned char,8> bytes)
{ {
static_assert(sizeof(IntegerType) >= sizeof...(Bytes), "IntegerType not large enough to contain bytes"); return ((IntegerType)(bytes[0] << 0)+
(IntegerType)(bytes[1] << 8)+
IntegerType integer = 0; (IntegerType)(bytes[2] << 16)+
std::size_t index = 0; (IntegerType)(bytes[3] << 24)+
return ((integer |= static_cast<IntegerType>(static_cast<IntegerType>(byte) << 8 * index++)), ...); (IntegerType)(bytes[4] << 32)+
(IntegerType)(bytes[5] << 40)+
(IntegerType)(bytes[6] << 48)+
(IntegerType)(bytes[7] << 56));
} }
[[nodiscard]] SFML_SYSTEM_API std::FILE* openFile(const std::filesystem::path& filename, std::string_view mode); [[nodiscard]] SFML_SYSTEM_API std::FILE* openFile(const ghc::filesystem::path& filename, std::string mode);
} // namespace sf } // namespace sf

View File

@@ -119,6 +119,6 @@ T Vector2<T>::length() const
// Explicit template instantiations // Explicit template instantiations
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template class sf::Vector2<float>; //template class Vector2<float>;
template class sf::Vector2<double>; //template class Vector2<double>;
template class sf::Vector2<long double>; //template class Vector2<long double>;

View File

@@ -60,6 +60,6 @@ T Vector3<T>::length() const
// Explicit template instantiations // Explicit template instantiations
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template class sf::Vector3<float>; //template class Vector3<float>;
template class sf::Vector3<double>; //template class Vector3<double>;
template class sf::Vector3<long double>; //template class Vector3<long double>;

View File

@@ -31,7 +31,7 @@
#include <mmsystem.h> #include <mmsystem.h>
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sleepImpl(Time time) void sleepImpl(Time time)
@@ -54,4 +54,4 @@ void sleepImpl(Time time)
timeEndPeriod(periodMin); timeEndPeriod(periodMin);
} }
} // namespace sf::priv } // namespace sf

View File

@@ -34,15 +34,15 @@ namespace sf
class Time; class Time;
} }
namespace sf::priv namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Windows implementation of sf::Sleep /// \brief Windows implementation of Sleep
/// ///
/// \param time Time to sleep /// \param time Time to sleep
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sleepImpl(Time time); void sleepImpl(Time time);
} // namespace sf::priv } // namespace sf

View File

@@ -52,16 +52,18 @@ case "$1" in
;; ;;
esac esac
# Intel builds target 10.10 (Yosemite.)
export MACOSX_DEPLOYMENT_TARGET=10.10
if [ -n "$APPLE_SILICON" ]; then if [ -n "$APPLE_SILICON" ]; then
if [ -n "$intel_target" ]; then if [ -n "$intel_target" ]; then
target_build_arch='-target x86_64-apple-macos10.15 -march=core2 -mtune=skylake' target_build_arch='-target x86_64-apple-macos10.15 -march=core2 -mtune=skylake'
target_cpu=x86_64 target_cpu=x86_64
export MACOSX_DEPLOYMENT_TARGET=10.15 # Catalina
else else
export MACOSX_DEPLOYMENT_TARGET=11.0 # Big Sur export MACOSX_DEPLOYMENT_TARGET=11.0 # Big Sur
fi fi
elif [ "$target_cpu" = x86_64 ]; then elif [ "$target_cpu" = x86_64 ]; then
target_build_arch='-m64 -march=core2 -mtune=skylake' target_build_arch="-m64 -march=core2 -mtune=skylake -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
fi fi
# Need to use Xcode 9 for 32 bit builds on Mojave and newer. # Need to use Xcode 9 for 32 bit builds on Mojave and newer.
@@ -80,6 +82,10 @@ elif [ -f /opt/homebrew/bin/brew ]; then
export BREW_PREFIX=$(/opt/homebrew/bin/brew --prefix) export BREW_PREFIX=$(/opt/homebrew/bin/brew --prefix)
fi fi
if [ -n "$BREW_PREFIX" ]; then
"$BREW_PREFIX"/bin/brew unlink gettext >/dev/null 2>&1 || :
fi
export BUILD_ROOT="${BUILD_ROOT:-$HOME/vbam-build-mac-${target_cpu}}$BUILD_ROOT_SUFFIX" export BUILD_ROOT="${BUILD_ROOT:-$HOME/vbam-build-mac-${target_cpu}}$BUILD_ROOT_SUFFIX"
ver_file=$(mktemp) ver_file=$(mktemp)
@@ -88,7 +94,7 @@ read -r macos_major macos_minor macos_patch < "$ver_file"
rm -f "$ver_file" rm -f "$ver_file"
# Find the highest version clang and llvm in Nix or Homebrew. # Find the highest version clang and llvm in Nix or Homebrew.
best_llvm=$( best_llvm_path=$(
( (
for nix_clang in $(find /nix/store -maxdepth 1 -type d -name '*-clang-[0-9]*[0-9]'); do for nix_clang in $(find /nix/store -maxdepth 1 -type d -name '*-clang-[0-9]*[0-9]'); do
llvm_ver=$(echo "$nix_clang" | sed -E 's/.*-([0-9][0-9.]*[0-9])$/\1/') llvm_ver=$(echo "$nix_clang" | sed -E 's/.*-([0-9][0-9.]*[0-9])$/\1/')
@@ -99,7 +105,7 @@ best_llvm=$(
fi fi
done done
for brew_llvm in $(find "$BREW_PREFIX"/Cellar -maxdepth 1 -type l -name 'llvm*'); do for brew_llvm in $(find "$BREW_PREFIX"/Cellar/llvm -maxdepth 1 -type d 2>/dev/null); do
if [ -x "$brew_llvm/bin/clang++" ]; then if [ -x "$brew_llvm/bin/clang++" ]; then
echo "$brew_llvm $($brew_llvm/bin/clang++ --version | head -1 | awk '{ print $NF }')" echo "$brew_llvm $($brew_llvm/bin/clang++ --version | head -1 | awk '{ print $NF }')"
fi fi
@@ -107,15 +113,19 @@ best_llvm=$(
) | sort -k2,2 -V -r | head -1 | awk '{ print $1 }' ) | sort -k2,2 -V -r | head -1 | awk '{ print $1 }'
) )
# Fallback to XCode version.
[ -z "$best_llvm_path" ] && best_llvm_path=/usr
clang_path=${best_llvm_path%%:*}
BUILD_ENV=$(cat <<EOF BUILD_ENV=$(cat <<EOF
export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET
export COMMAND_MODE=unix2003 export COMMAND_MODE=unix2003
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:"$BREW_PREFIX"/bin export PATH="$best_llvm_path/bin:/usr/bin:/bin:/usr/sbin:/sbin:$BREW_PREFIX/bin"
[ -n "$best_llvm" ] && export PATH="$best_llvm/bin:\$PATH" export CC="$clang_path/bin/clang"
export CPP="$clang_path/bin/clang -E"
export CC=clang export CXX="$clang_path/bin/clang++"
export CXX=clang++
export CPPFLAGS=-DICONV_CONST= export CPPFLAGS=-DICONV_CONST=
export CFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind" export CFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"
export CXXFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind" export CXXFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"