/************************************************************************************ * * D++, A Lightweight C++ library for Discord * * SPDX-License-Identifier: Apache-2.0 * Copyright 2021 Craig Edwards and D++ contributors * (https://github.com/brainboxdotcc/DPP/graphs/contributors) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ************************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include /** * @brief The main namespace for D++ functions, classes and types */ namespace dpp { enum sticker_format : uint8_t; /** * @brief Macro that expands to static_asserts checking sizeof and alignof are equal between two types. */ #define DPP_CHECK_ABI_COMPAT(a, b) \ static_assert(sizeof(a) == sizeof(b), #a " and " #b " must be the same size for ABI compatibility"); \ static_assert(alignof(a) == alignof(b), #a " and " #b " must be the same alignment for ABI compatibility"); \ /** * @brief Utility helper functions, generally for logging, running programs, time/date manipulation, etc */ namespace utility { /** * @brief Helper function to easily create discord's cdn endpoint urls. * @warning **For internal use only!** * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param allowed_formats A vector of supported formats for the endpoint from the discord docs * @param path_without_extension The path for the endpoint (without the extension e.g. `.png`) * @param format the wished format to return. Must be one of the formats passed in `allowed_formats`, otherwise it returns an empty string * @param size the image size which will be appended as a querystring to the url. * It must be any power of two between 16 and 4096, otherwise no querystring will be appended (discord then returns the image as their default size) * @param prefer_animated Whether the user prefers gif format. If true, it'll return gif format whenever the image is available as animated. * In this case, the `format`-parameter is only used for non-animated images. * @param is_animated Whether the image is actually animated or not * @return std::string endpoint url or empty string */ std::string DPP_EXPORT cdn_endpoint_url(const std::vector &allowed_formats, const std::string &path_without_extension, const dpp::image_type format, uint16_t size, bool prefer_animated = false, bool is_animated = false); /** * @brief Helper function to easily create discord's cdn endpoint urls. * @warning **For internal use only!** * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param allowed_formats A vector of supported formats for the endpoint from the discord docs * @param path_without_extension The path for the endpoint (without the extension e.g. `.png`) * @param hash The hash (optional). If not empty, it will be prefixed with `a_` for animated images (`is_animated`=true) * @param format the wished format to return. Must be one of the formats passed in `allowed_formats`, otherwise it returns an empty string * @param size the image size which will be appended as a querystring to the url. * It must be any power of two between 16 and 4096, otherwise no querystring will be appended (discord then returns the image as their default size) * @param prefer_animated Whether the user prefers gif format. If true, it'll return gif format whenever the image is available as animated. * In this case, the `format`-parameter is only used for non-animated images. * @param is_animated Whether the image is actually animated or not * @return std::string endpoint url or empty string */ std::string DPP_EXPORT cdn_endpoint_url_hash(const std::vector &allowed_formats, const std::string &path_without_extension, const std::string &hash, const dpp::image_type format, uint16_t size, bool prefer_animated = false, bool is_animated = false); /** * @brief Helper function to easily create discord's cdn endpoint urls (specialised for stickers) * @warning **For internal use only!** * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param sticker_id The sticker ID. Returns empty string if 0 * @param format The format type * @return std::string endpoint url or empty string */ std::string DPP_EXPORT cdn_endpoint_url_sticker(snowflake sticker_id, sticker_format format); /** * @brief Supported AVX instruction set type for audio mixing */ enum avx_type_t : uint8_t { /** * @brief No AVX Support */ avx_none, /** * @brief AVX support */ avx_1, /** * @brief AVX2 support */ avx_2, /** * @brief AVX512 support */ avx_512, }; /** * @brief Timestamp formats for dpp::utility::timestamp() * * @note These values are the actual character values specified by the Discord API * and should not be changed unless the Discord API changes the specification! * They have been sorted into numerical order of their ASCII value to keep C++ happy. */ enum time_format : uint8_t { /** * @brief "20 April 2021" - Long Date */ tf_long_date = 'D', /** * @brief "Tuesday, 20 April 2021 16:20" - Long Date/Time */ tf_long_datetime = 'F', /** * @brief "2 months ago" - Relative Time */ tf_relative_time = 'R', /** * @brief "16:20:30" - Long Time */ tf_long_time = 'T', /** * @brief "20/04/2021" - Short Date */ tf_short_date = 'd', /** * @brief "20 April 2021 16:20" - Short Date/Time */ tf_short_datetime = 'f', /** * @brief "16:20" - Short Time */ tf_short_time = 't', }; /** * @brief Guild navigation types for dpp::utility::guild_navigation() */ enum guild_navigation_type { /** * @brief _Customize_ tab with the server's dpp::onboarding_prompt */ gnt_customize, /** * @brief "16:20" _Browse Channels_ tab */ gnt_browse, /** * @brief Server Guide */ gnt_guide, }; /** * @brief The base URL for CDN content such as profile pictures and guild icons. */ inline const std::string cdn_host = "https://cdn.discordapp.com"; /** * @brief The base URL for message/user/channel links. */ inline const std::string url_host = "https://discord.com"; /** * @brief Callback for the results of a command executed via dpp::utility::exec */ typedef std::function cmd_result_t; /** * @brief Run a commandline program asynchronously. The command line program * is spawned in a separate std::thread, and when complete, its output from * stdout is passed to the callback function in its string parameter. For example: * ```cpp * dpp::utility::exec("/bin/ls", {"-al"}, [](const std::string& output) { * std::cout << "Output of 'ls -al': " << output << "\n"; * }); * ``` * * @param cmd The command to run. * @param parameters Command line parameters. Each will be escaped using `std::quoted`. * @param callback The callback to call on completion. */ void DPP_EXPORT exec(const std::string& cmd, std::vector parameters = {}, cmd_result_t callback = {}); /** * @brief Return a mentionable timestamp (used in a message). These timestamps will display the given timestamp in the user's timezone and locale. * * @param ts Time stamp to convert * @param tf Format of timestamp using dpp::utility::time_format * @return std::string The formatted timestamp */ std::string DPP_EXPORT timestamp(time_t ts, time_format tf = tf_short_datetime); /** * @brief Create a mentionable guild navigation (used in a message). * * @param guild_id The guild ID * @param gnt Guild navigation type using dpp::utility::guild_navigation_type * @return std::string The formatted timestamp */ std::string DPP_EXPORT guild_navigation(const snowflake guild_id, guild_navigation_type gnt); /** * @brief Returns current date and time * * @return std::string Current date and time in "Y-m-d H:M:S" format */ std::string DPP_EXPORT current_date_time(); /** * @brief Convert a dpp::loglevel enum value to a string * * @param in log level to convert * @return std::string string form of log level */ std::string DPP_EXPORT loglevel(dpp::loglevel in); /** * @brief Store a 128 bit icon hash (profile picture, server icon etc) * as a 128 bit binary value made of two uint64_t. * Has a constructor to build one from a string, and a method to fetch * the value back in string form. */ struct DPP_EXPORT iconhash { /** * @brief High 64 bits. */ uint64_t first; /** * @brief Low 64 bits. */ uint64_t second; /** * @brief Construct a new iconhash object * @param _first Leftmost portion of the hash value * @param _second Rightmost portion of the hash value */ iconhash(uint64_t _first = 0, uint64_t _second = 0) noexcept; /** * @brief Construct a new iconhash object * * @param hash String hash to construct from. * Must contain a 32 character hex string. * * @throws std::length_error if the provided * string is not exactly 32 characters long. */ iconhash(const std::string &hash); /** * @brief Assign from std::string * * @param assignment string to assign from. * * @throws std::length_error if the provided * string is not exactly 32 characters long. */ iconhash& operator=(const std::string &assignment); /** * @brief Check if one iconhash is equal to another * * @param other other iconhash to compare * @return True if the iconhash objects match */ bool operator==(const iconhash& other) const noexcept; /** * @brief Change value of iconhash object * * @param hash String hash to change to. * Must contain a 32 character hex string. * * @throws std::length_error if the provided * string is not exactly 32 characters long. */ void set(const std::string &hash); /** * @brief Convert iconhash back to 32 character * string value. * * @return std::string Hash value */ std::string to_string() const; }; /** * @brief Image to be received or sent to API calls. * * This class is carefully crafted to be 16 bytes, * this is why we use a ptr + 4 byte size instead of a vector. * We want this class to be substitutable with iconhash in data structures. */ struct DPP_EXPORT image_data { /** * @brief Data in bytes of the image. */ std::unique_ptr data = nullptr; /** * @brief Size of the data in bytes. */ uint32_t size = 0; /** * @brief Type of the image. * * @see image_type */ image_type type = {}; /** * @brief Construct an empty image. */ image_data() = default; /** * @brief Copy an image. * * @param rhs Image to copy */ image_data(const image_data& rhs); /** * @brief Move an image. * * @param rhs Image to copy */ image_data(image_data&&) noexcept = default; /** * @brief Construct from string buffer * * @param format Image format * @param str Data in a string * @see image_type */ image_data(image_type format, std::string_view bytes); /** * @brief Construct from byte buffer * * @param format Image format * @param buf Byte buffer * @param size_t Image size in bytes * @see image_type */ image_data(image_type format, const std::byte* bytes, uint32_t byte_size); /** * @brief Copy an image data. * * @param rhs Image to copy * @return self for chaining */ image_data& operator=(const image_data& rhs); /** * @brief Move an image data. * * @param rhs Image to move from * @return self for chaining */ image_data& operator=(image_data&& rhs) noexcept = default; /** * @brief Set image data. * * @param format Format of the image * @param data Data of the image */ void set(image_type format, std::string_view bytes); /** * @brief Set image data. * * @param format Format of the image * @param data Data of the image */ void set(image_type format, const std::byte* bytes, uint32_t byte_size); /** * @brief Encode to base64. * * @return std::string New string with the image data encoded in base64 */ std::string base64_encode() const; /** * @brief Get the file extension. * * Alias for \ref file_extension * @return std::string File extension e.g. `.png` */ std::string get_file_extension() const; /** * @brief Get the mime type. * * Alias for \ref mime_type * @return std::string File mime type e.g. "image/png" */ std::string get_mime_type() const; /** * @brief Check if this is an empty image. * * @return bool Whether the image is empty or not */ bool empty() const noexcept; /** * @brief Build a data URI scheme suitable for sending to Discord * * @see https://discord.com/developers/docs/reference#image-data * @return The data URI scheme as a json or null if empty */ json to_nullable_json() const; }; /** * @brief Wrapper class around a variant for either iconhash or image, * for API objects that have one or the other (generally iconhash when receiving, * image when uploading an image) */ struct icon { /** * @brief Iconhash received or image data for upload. */ std::variant hash_or_data; /** * @brief Assign to iconhash. * * @param hash Iconhash */ icon& operator=(const iconhash& hash); /** * @brief Assign to iconhash. * * @param hash Iconhash */ icon& operator=(iconhash&& hash) noexcept; /** * @brief Assign to image. * * @param img Image */ icon& operator=(const image_data& img); /** * @brief Assign to image. * * @param img Image */ icon& operator=(image_data&& img) noexcept; /** * @brief Check whether this icon is stored as an iconhash * * @see iconhash * @return bool Whether this icon is stored as an iconhash */ bool is_iconhash() const; /** * @brief Get as icon hash. * * @warn The behavior is undefined if `is_iconhash() == false` * @return iconhash& This iconhash */ iconhash& as_iconhash() &; /** * @brief Get as icon hash. * * @warn The behavior is undefined if `is_iconhash() == false` * @return iconhash& This iconhash */ const iconhash& as_iconhash() const&; /** * @brief Get as icon hash. * * @warn The behavior is undefined if `is_iconhash() == false` * @return iconhash& This iconhash */ iconhash&& as_iconhash() &&; /** * @brief Check whether this icon is stored as an image * * @see image_data * @return bool Whether this icon is stored as an image */ bool is_image_data() const; /** * @brief Get as image data. * * @warn The behavior is undefined if `is_image_data() == false` * @return image_data& This image */ image_data& as_image_data() &; /** * @brief Get as image. * * @warn The behavior is undefined if `is_image_data() == false` * @return image_data& This image */ const image_data& as_image_data() const&; /** * @brief Get as image. * * @warn The behavior is undefined if `is_image_data() == false` * @return image_data& This image */ image_data&& as_image_data() &&; }; /** * @brief Return the current time with fractions of seconds. * This is a unix epoch time with the fractional seconds part * after the decimal place. * * @return double time with fractional seconds */ double DPP_EXPORT time_f(); /** * @brief Returns true if D++ was built with voice support * * @return bool True if voice support is compiled in (libsodium/libopus) */ bool DPP_EXPORT has_voice(); /** * @brief Returns an enum value indicating which AVX instruction * set is used for mixing received voice data, if any * * @return avx_type_t AVX type */ avx_type_t DPP_EXPORT voice_avx(); /** * @brief Returns true if D++ was built with coroutine support * * @return bool True if coroutines are supported */ bool DPP_EXPORT is_coro_enabled(); /** * @brief Convert a byte count to display value * * @param c number of bytes * @return std::string display value suffixed with M, G, T where necessary */ std::string DPP_EXPORT bytes(uint64_t c); /** * @brief A class used to represent an uptime in hours, minutes, * seconds and days, with helper functions to convert from time_t * and display as a string. */ struct DPP_EXPORT uptime { /** * @brief Number of days. */ uint16_t days; /** * @brief Number of hours. */ uint8_t hours; /** * @brief Number of minutes. */ uint8_t mins; /** * @brief Number of seconds. */ uint8_t secs; /** * @brief Construct a new uptime object */ uptime(); /** * @brief Construct a new uptime object * * @param diff A time_t to initialise the object from */ uptime(time_t diff); /** * @brief Construct a new uptime object * * @param diff A time_t to initialise the object from */ uptime(double diff); /** * @brief Get uptime as string * * @return std::string Uptime as string */ std::string to_string() const; /** * @brief Get uptime as seconds * * @return uint64_t Uptime as seconds */ uint64_t to_secs() const; /** * @brief Get uptime as milliseconds * * @return uint64_t Uptime as milliseconds */ uint64_t to_msecs() const; }; /** * @brief Convert doubles to RGB for sending in embeds * * @param red red value, between 0 and 1 inclusive * @param green green value, between 0 and 1 inclusive * @param blue blue value, between 0 and 1 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT rgb(double red, double green, double blue); /** * @brief Convert ints to RGB for sending in embeds * * @param red red value, between 0 and 255 inclusive * @param green green value, between 0 and 255 inclusive * @param blue blue value, between 0 and 255 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT rgb(int red, int green, int blue); /** * @brief Convert doubles to CMYK for sending in embeds * * @param c cyan value, between 0 and 1 inclusive * @param m magenta value, between 0 and 1 inclusive * @param y yellow value, between 0 and 1 inclusive * @param k key (black) value, between 0 and 1 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT cmyk(double c, double m, double y, double k); /** * @brief Convert ints to CMYK for sending in embeds * * @param c cyan value, between 0 and 255 inclusive * @param m magenta value, between 0 and 255 inclusive * @param y yellow value, between 0 and 255 inclusive * @param k key (black) value, between 0 and 255 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT cmyk(int c, int m, int y, int k); /** * @brief Convert doubles to HSL for sending in embeds * * @param h hue value, between 0 and 1 inclusive * @param s saturation value in percentage, between 0 and 1 inclusive * @param l lightness value in percentage, between 0 and 1 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT hsl(double h, double s, double l); /** * @brief Convert ints to HSL for sending in embeds * * @param h hue value, between 0 and 360 inclusive * @param s saturation value in percentage, between 0 and 100 inclusive * @param l lightness value in percentage, between 0 and 100 inclusive * @return uint32_t returned integer colour value */ uint32_t DPP_EXPORT hsl(int h, int s, int l); /** * @brief Output hex values of a section of memory for debugging * * @param data The start of the data to display * @param length The length of data to display */ std::string DPP_EXPORT debug_dump(uint8_t* data, size_t length); /** * @brief Returns the length of a UTF-8 string in codepoints * * @param str string to count length of * @return size_t length of string (0 for invalid utf8) */ size_t DPP_EXPORT utf8len(const std::string &str); /** * @brief Return substring of a UTF-8 encoded string in codepoints * * @param str string to return substring from * @param start start codepoint offset * @param length length in codepoints * @return std::string Substring in UTF-8 or empty string if invalid UTF-8 passed in */ std::string DPP_EXPORT utf8substr(const std::string& str, std::string::size_type start, std::string::size_type length); /** * @brief Read a whole file into a std::string. * @note This function can take a while if this is a large file, causing events to not reply and also taking up a lot of memory. Make sure you have enough memory, and use dpp::interaction_create_t::thinking in events where you call this function on big files. * @warning Be aware this function can block! If you are regularly reading large files, consider caching them. * @param filename The path to the file to read * @return std::string The file contents * @throw dpp::file_exception on failure to read the entire file */ std::string DPP_EXPORT read_file(const std::string& filename); /** * @brief Validate a string value * In the event the length of the string is less than _min, then an exception of type dpp:length_exception * will be thrown. If the string is longer than _max UTF8 codepoints it will be truncated to fit. * * @param value The value to validate * @param _min Minimum length * @param _max Maximum length * @param exception_message Exception message to throw if value length < _min * @return std::string Validated string, truncated if necessary. * @throw dpp::length_exception if value UTF8 length < _min */ std::string DPP_EXPORT validate(const std::string& value, size_t _min, size_t _max, const std::string& exception_message); /** * @brief Get the url query parameter for the cdn endpoint. Internally used to build url getters. * * @param size size to generate url parameter for. Must be any power of two between 16 and 4096 (inclusive) or it'll return an empty string. * @return std::string url query parameter e.g. `?size=128`, or an empty string */ std::string DPP_EXPORT avatar_size(uint32_t size); /** * @brief Split (tokenize) a string into a vector, using the given separators * * @param in Input string * @param sep Separator characters * @return std::vector Tokenized strings */ std::vector DPP_EXPORT tokenize(std::string const &in, const char* sep = "\r\n"); /** * @brief Create a bot invite * * @param bot_id Bot ID * @param permissions Permission bitmask of the bot to invite * @param scopes Scopes to use * @return Invite URL */ std::string DPP_EXPORT bot_invite_url(const snowflake bot_id, const uint64_t permissions = 0, const std::vector& scopes = {"bot", "applications.commands"}); /** * @brief Escapes Discord's markdown sequences in a string * * @param text Text to escape * @param escape_code_blocks If set to false, then code blocks are not escaped. * This means that you can still use a code block, and the text within will be left as-is. * If set to true, code blocks will also be escaped so that ` symbol may be used as a normal * character. * @return std::string The text with the markdown special characters escaped with a backslash */ std::string DPP_EXPORT markdown_escape(const std::string& text, bool escape_code_blocks = false); /** * @brief Encodes a url parameter similar to [php urlencode()](https://www.php.net/manual/en/function.urlencode.php) * * @param value String to encode * @return std::string URL encoded string */ std::string DPP_EXPORT url_encode(const std::string &value); /** * @brief Create a mentionable slashcommand (used in a message). * @param command_id The ID of the slashcommand * @param command_name The command name * @param subcommand Optional: The subcommand name (for mentioning a subcommand) * @return std::string The formatted mention */ std::string DPP_EXPORT slashcommand_mention(snowflake command_id, const std::string &command_name, const std::string &subcommand = ""); /** * @brief Create a mentionable slashcommand (used in a message). * @param command_id The ID of the slashcommand * @param command_name The command name * @param subcommand_group The subcommand group name * @param subcommand The subcommand name * @return std::string The formatted mention of the slashcommand with its subcommand */ std::string DPP_EXPORT slashcommand_mention(snowflake command_id, const std::string &command_name, const std::string &subcommand_group, const std::string &subcommand); /** * @brief Create a mentionable user. * @param id The ID of the user. * @return std::string The formatted mention of the user. */ std::string DPP_EXPORT user_mention(const snowflake& id); /** * @brief Create a mentionable channel. * @param id The ID of the channel. * @return std::string The formatted mention of the channel. */ std::string DPP_EXPORT channel_mention(const snowflake& id); /** * @brief Create a mentionable emoji * @param name The name of the emoji. * @param id The ID of the emoji. * @param is_animated is emoji animated. * @return std::string The formatted mention of the emoji. */ std::string DPP_EXPORT emoji_mention(std::string_view name, snowflake id, bool is_animated = false); /** * @brief Create a mentionable role. * @param id The ID of the role. * @return std::string The formatted mention of the role. */ std::string DPP_EXPORT role_mention(const snowflake& id); /** * @brief Create a URL for message. * @param guild_id The ID of the guild where message is written. * @param channel_id The ID of the channel where message is written. * @param message_id The ID of the message. * @return std::string The URL to message or empty string if any of ids is 0. */ std::string DPP_EXPORT message_url(const snowflake& guild_id, const snowflake& channel_id, const snowflake& message_id); /** * @brief Create a URL for message. * @param guild_id The ID of the guild where channel is located. * @param channel_id The ID of the channel. * @return std::string The URL to message or empty string if any of ids is 0. */ std::string DPP_EXPORT channel_url(const snowflake& guild_id, const snowflake& channel_id); /** * @brief Create a URL for message. * @param guild_id The ID of the guild where thread is located. * @param thread_id The ID of the thread. * @return std::string The URL to message or empty string if any of ids is 0. */ std::string DPP_EXPORT thread_url(const snowflake& guild_id, const snowflake& thread_id); /** * @brief Create a URL for message. * @param user_id The ID of the guild where thread is located. * @return std::string The URL to message or empty string if id is 0. */ std::string DPP_EXPORT user_url(const snowflake& user_id); #ifdef _DOXYGEN_ /** * @brief Get the mime type for an image type. * @param type Image type * @return std::string The mime type for this image type */ std::string DPP_EXPORT mime_type(image_type type); /** * @brief Get the mime type for a sticker format. * @param format Sticker format * @return std::string The mime type for this sticker format */ std::string DPP_EXPORT mime_type(sticker_format format); /** * @brief Get the file extension for an image type. * @param type Image type * @return std::string The file extension (e.g. ".png") for this image type */ std::string DPP_EXPORT file_extension(image_type type); /** * @brief Get the file extension for a sticker format. * @param format Sticker format * @return std::string The file extension (e.g. ".png") for this sticker format */ std::string DPP_EXPORT file_extension(sticker_format format); #else /** * @brief Get the mime type for an image type. * @param type Image type * @return std::string The mime type for this image type */ template extern std::enable_if_t, std::string> DPP_EXPORT mime_type(T type); /** * @brief Get the mime type for a sticker format. * @param format Sticker format * @return std::string The mime type for this sticker format */ template extern std::enable_if_t, std::string> DPP_EXPORT mime_type(T format); /** * @brief Get the file extension for an image type. * @param type Image type * @return std::string The file extension (e.g. ".png") for this image type */ template extern std::enable_if_t, std::string> DPP_EXPORT file_extension(T type); /** * @brief Get the file extension for a sticker format. * @param format Sticker format * @return std::string The file extension (e.g. ".png") for this sticker format */ template extern std::enable_if_t, std::string> DPP_EXPORT file_extension(T format); #endif /** * @brief Returns the library's version string * * @return std::string version */ std::string DPP_EXPORT version(); /** * @brief Build a URL parameter string e.g. "?a=b&c=d&e=f" from a map of key/value pairs. * Entries with empty key names or values are omitted. * * @param parameters parameters to create a url query string for * @return std::string A correctly encoded url query string */ std::string DPP_EXPORT make_url_parameters(const std::map& parameters); /** * @brief Build a URL parameter string e.g. "?a=b&c=d&e=f" from a map of key/value pairs. * Entries with empty key names or zero values are omitted. * * @param parameters parameters to create a url query string for * @return std::string A correctly encoded url query string */ std::string DPP_EXPORT make_url_parameters(const std::map& parameters); /** * @brief Set the name of the current thread for debugging and statistical reporting * * @param name New name to set */ void DPP_EXPORT set_thread_name(const std::string& name); #ifdef __cpp_concepts // if c++20 /** * @brief Concept satisfied if a callable F can be called using the arguments Args, and that its return value is convertible to R. * * @tparam F Callable object * @tparam R Return type to check for convertibility to * @tparam Args... Arguments to use to resolve the overload * @return Whether the expression `F(Args...)` is convertible to R */ template concept callable_returns = std::convertible_to, R>; /** * @brief Type trait to check if a callable F can be called using the arguments Args, and that its return value is convertible to R. * * @deprecated In C++20 mode, prefer using the concept `callable_returns`. * @tparam F Callable object * @tparam R Return type to check for convertibility to * @tparam Args... Arguments to use to resolve the overload * @return Whether the expression `F(Args...)` is convertible to R */ template inline constexpr bool callable_returns_v = callable_returns; #else /** * @brief Type trait to check if a callable F can be called using the arguments Args, and that its return value is convertible to R. * * @tparam F Callable object * @tparam R Return type to check for convertibility to * @tparam Args... Arguments to use to resolve the overload * @return Whether the expression `F(Args...)` is convertible to R */ template inline constexpr bool callable_returns_v = std::is_convertible_v, R>; #endif /** * @brief Utility struct that has the same size and alignment as another but does nothing. Useful for ABI compatibility. * * @tparam T Type to mimic */ template struct alignas(T) dummy { /** @brief Array of bytes with a size mimicking T */ std::array data; }; } // namespace utility } // namespace dpp