From eea89d4ae353a051987a3fc75355653a153e0174 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Mon, 16 May 2022 21:57:46 +0200 Subject: [PATCH] chore: Replace nonstd::optional with std::optional --- LICENSE.adoc | 35 - src/Args.cpp | 6 +- src/Args.hpp | 4 +- src/Config.cpp | 15 +- src/Config.hpp | 11 +- src/Context.hpp | 6 +- src/Depfile.cpp | 8 +- src/Depfile.hpp | 8 +- src/Logging.hpp | 2 +- src/Result.cpp | 4 +- src/Result.hpp | 4 +- src/ResultExtractor.cpp | 2 +- src/ResultExtractor.hpp | 2 +- src/ResultInspector.cpp | 4 +- src/ResultInspector.hpp | 2 +- src/ResultRetriever.cpp | 2 +- src/ResultRetriever.hpp | 2 +- src/UmaskScope.hpp | 10 +- src/Util.cpp | 12 +- src/Util.hpp | 6 +- src/argprocessing.cpp | 126 +- src/argprocessing.hpp | 6 +- src/ccache.cpp | 38 +- src/core/Manifest.cpp | 4 +- src/core/Manifest.hpp | 5 +- src/core/exceptions.hpp | 2 +- src/core/mainoptions.cpp | 13 +- src/storage/Storage.cpp | 8 +- src/storage/Storage.hpp | 10 +- src/storage/primary/CacheFile.hpp | 7 +- src/storage/primary/PrimaryStorage.cpp | 22 +- src/storage/primary/PrimaryStorage.hpp | 31 +- .../primary/PrimaryStorage_cleanup.cpp | 14 +- .../primary/PrimaryStorage_compress.cpp | 6 +- src/storage/primary/StatsFile.cpp | 6 +- src/storage/primary/StatsFile.hpp | 7 +- src/storage/secondary/FileStorage.cpp | 11 +- src/storage/secondary/HttpStorage.cpp | 7 +- src/storage/secondary/RedisStorage.cpp | 13 +- src/storage/secondary/SecondaryStorage.hpp | 8 +- src/third_party/nonstd/optional.hpp | 1807 ----------------- src/util/Tokenizer.hpp | 3 +- src/util/string.cpp | 12 +- src/util/string.hpp | 14 +- unittest/test_Args.cpp | 2 +- unittest/test_Config.cpp | 4 +- unittest/test_Util.cpp | 4 +- unittest/test_ccache.cpp | 3 +- unittest/test_util_string.cpp | 23 +- 49 files changed, 246 insertions(+), 2115 deletions(-) delete mode 100644 src/third_party/nonstd/optional.hpp diff --git a/LICENSE.adoc b/LICENSE.adoc index d2f5239e4..407f3971f 100644 --- a/LICENSE.adoc +++ b/LICENSE.adoc @@ -609,41 +609,6 @@ DEALINGS IN THE SOFTWARE. ---- -=== src/third_party/nonstd/optional.hpp - -This is the single header version of -https://github.com/martinmoene/optional-lite[optional-lite] 3.5.0 with the -following license: - ----- -Copyright (c) 2014-2021 Martin Moene - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -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, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. ----- - - === src/third_party/nonstd/string_view.hpp This alternative implementation of `std::string_view` was downloaded from diff --git a/src/Args.cpp b/src/Args.cpp index 09aa8482d..b965f6fe1 100644 --- a/src/Args.cpp +++ b/src/Args.cpp @@ -23,8 +23,6 @@ #include #include -using nonstd::nullopt; -using nonstd::optional; using nonstd::string_view; Args::Args(Args&& other) noexcept : m_args(std::move(other.m_args)) @@ -49,14 +47,14 @@ Args::from_string(const std::string& command) return args; } -optional +std::optional Args::from_atfile(const std::string& filename, AtFileFormat format) { std::string argtext; try { argtext = Util::read_text_file(filename); } catch (core::Error&) { - return nullopt; + return std::nullopt; } Args args; diff --git a/src/Args.hpp b/src/Args.hpp index d55ecd41a..f0ffd9489 100644 --- a/src/Args.hpp +++ b/src/Args.hpp @@ -21,10 +21,10 @@ #include "NonCopyable.hpp" #include "Util.hpp" -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" #include +#include #include class Args @@ -42,7 +42,7 @@ public: static Args from_argv(int argc, const char* const* argv); static Args from_string(const std::string& command); - static nonstd::optional + static std::optional from_atfile(const std::string& filename, AtFileFormat format = AtFileFormat::gcc); diff --git a/src/Config.cpp b/src/Config.cpp index ee4cd9f7f..5e239e47a 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -46,9 +46,6 @@ #include #include -using nonstd::nullopt; -using nonstd::optional; - #ifndef environ DLLIMPORT extern char** environ; #endif @@ -196,7 +193,7 @@ const std::unordered_map k_env_variable_table = { bool parse_bool(const std::string& value, - const optional env_var_key, + const std::optional env_var_key, bool negate) { if (env_var_key) { @@ -348,7 +345,7 @@ format_sloppiness(core::Sloppiness sloppiness) } std::string -format_umask(nonstd::optional umask) +format_umask(std::optional umask) { if (umask) { return FMT("{:03o}", *umask); @@ -574,7 +571,7 @@ Config::update_from_file(const std::string& path) return parse_config_file( path, [&](const auto& /*line*/, const auto& key, const auto& value) { if (!key.empty()) { - this->set_item(key, value, nullopt, false, path); + this->set_item(key, value, std::nullopt, false, path); } }); } @@ -767,7 +764,7 @@ Config::set_value_in_file(const std::string& path, // Verify that the value is valid; set_item will throw if not. Config dummy_config; - dummy_config.set_item(key, value, nullopt, false, ""); + dummy_config.set_item(key, value, std::nullopt, false, ""); const auto resolved_path = Util::real_path(path); const auto st = Stat::stat(resolved_path); @@ -823,7 +820,7 @@ Config::visit_items(const ItemVisitor& item_visitor) const void Config::set_item(const std::string& key, const std::string& value, - const optional& env_var_key, + const std::optional& env_var_key, bool negate, const std::string& origin) { @@ -938,7 +935,7 @@ Config::set_item(const std::string& key, case ConfigItem::max_files: m_max_files = util::value_or_throw( - util::parse_unsigned(value, nullopt, nullopt, "max_files")); + util::parse_unsigned(value, std::nullopt, std::nullopt, "max_files")); break; case ConfigItem::max_size: diff --git a/src/Config.hpp b/src/Config.hpp index 6275fa659..fabe0e1d9 100644 --- a/src/Config.hpp +++ b/src/Config.hpp @@ -23,11 +23,10 @@ #include -#include "third_party/nonstd/optional.hpp" - #include #include #include +#include #include #include @@ -83,7 +82,7 @@ public: const std::string& stats_log() const; const std::string& namespace_() const; const std::string& temporary_dir() const; - nonstd::optional umask() const; + std::optional umask() const; // Return true for Clang and clang-cl. bool is_compiler_group_clang() const; @@ -187,7 +186,7 @@ private: std::string m_stats_log; std::string m_namespace; std::string m_temporary_dir; - nonstd::optional m_umask; + std::optional m_umask; bool m_temporary_dir_configured_explicitly = false; @@ -195,7 +194,7 @@ private: void set_item(const std::string& key, const std::string& value, - const nonstd::optional& env_var_key, + const std::optional& env_var_key, bool negate, const std::string& origin); @@ -462,7 +461,7 @@ Config::temporary_dir() const return m_temporary_dir; } -inline nonstd::optional +inline std::optional Config::umask() const { return m_umask; diff --git a/src/Context.hpp b/src/Context.hpp index b681ddeaf..650ceee28 100644 --- a/src/Context.hpp +++ b/src/Context.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Joel Rosdahl and other contributors +// Copyright (C) 2020-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -32,10 +32,10 @@ #include -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" #include +#include #include #include #include @@ -107,7 +107,7 @@ public: // Original umask before applying the `umask`/`CCACHE_UMASK` configuration, or // `nullopt` if there is no such configuration. - nonstd::optional original_umask; + std::optional original_umask; #ifdef MTR_ENABLED // Internal tracing. diff --git a/src/Depfile.cpp b/src/Depfile.cpp index 3fcc0bcd7..9bb6219f3 100644 --- a/src/Depfile.cpp +++ b/src/Depfile.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Joel Rosdahl and other contributors +// Copyright (C) 2020-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -57,7 +57,7 @@ escape_filename(nonstd::string_view filename) return result; } -nonstd::optional +std::optional rewrite_paths(const Context& ctx, const std::string& file_content) { ASSERT(!ctx.config.base_dir().empty()); @@ -65,7 +65,7 @@ rewrite_paths(const Context& ctx, const std::string& file_content) // Fast path for the common case: if (file_content.find(ctx.config.base_dir()) == std::string::npos) { - return nonstd::nullopt; + return std::nullopt; } std::string adjusted_file_content; @@ -104,7 +104,7 @@ rewrite_paths(const Context& ctx, const std::string& file_content) if (content_rewritten) { return adjusted_file_content; } else { - return nonstd::nullopt; + return std::nullopt; } } diff --git a/src/Depfile.hpp b/src/Depfile.hpp index 050700683..0ca6a0cb3 100644 --- a/src/Depfile.hpp +++ b/src/Depfile.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Joel Rosdahl and other contributors +// Copyright (C) 2020-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -23,17 +23,17 @@ class Hash; #include "Digest.hpp" -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" +#include #include #include namespace Depfile { std::string escape_filename(nonstd::string_view filename); -nonstd::optional rewrite_paths(const Context& ctx, - const std::string& file_content); +std::optional rewrite_paths(const Context& ctx, + const std::string& file_content); void make_paths_relative_in_output_dep(const Context& ctx); std::vector tokenize(nonstd::string_view file_content); diff --git a/src/Logging.hpp b/src/Logging.hpp index 7ed70faef..b6b6ce981 100644 --- a/src/Logging.hpp +++ b/src/Logging.hpp @@ -22,9 +22,9 @@ #include "third_party/fmt/core.h" #include "third_party/fmt/format.h" -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" +#include #include #include diff --git a/src/Result.cpp b/src/Result.cpp index 36ff33997..c4e3b65a3 100644 --- a/src/Result.cpp +++ b/src/Result.cpp @@ -69,8 +69,6 @@ // ::= // ::= uint64_t ; XXH3 of content bytes -using nonstd::nullopt; -using nonstd::optional; using nonstd::string_view; namespace { @@ -252,7 +250,7 @@ Reader::read_entry(uint8_t entry_number, Reader::Consumer& consumer) const auto file_len = m_reader.read_int(); if (marker == k_embedded_file_marker) { - consumer.on_entry_start(entry_number, file_type, file_len, nullopt); + consumer.on_entry_start(entry_number, file_type, file_len, std::nullopt); uint8_t buf[CCACHE_READ_BUFFER_SIZE]; size_t remain = file_len; diff --git a/src/Result.hpp b/src/Result.hpp index 6c85fe0d3..65aec25ab 100644 --- a/src/Result.hpp +++ b/src/Result.hpp @@ -21,10 +21,10 @@ #include #include "third_party/nonstd/expected.hpp" -#include "third_party/nonstd/optional.hpp" #include #include +#include #include #include @@ -112,7 +112,7 @@ public: virtual void on_entry_start(uint8_t entry_number, FileType file_type, uint64_t file_len, - nonstd::optional raw_file) = 0; + std::optional raw_file) = 0; virtual void on_entry_data(const uint8_t* data, size_t size) = 0; virtual void on_entry_end() = 0; }; diff --git a/src/ResultExtractor.cpp b/src/ResultExtractor.cpp index d5e30c0c7..6eb8e06e6 100644 --- a/src/ResultExtractor.cpp +++ b/src/ResultExtractor.cpp @@ -37,7 +37,7 @@ void ResultExtractor::on_entry_start(uint8_t /*entry_number*/, Result::FileType file_type, uint64_t /*file_len*/, - nonstd::optional raw_file) + std::optional raw_file) { std::string suffix = Result::file_type_to_string(file_type); if (suffix == Result::k_unknown_file_type) { diff --git a/src/ResultExtractor.hpp b/src/ResultExtractor.hpp index c34392f63..b6bbc1e13 100644 --- a/src/ResultExtractor.hpp +++ b/src/ResultExtractor.hpp @@ -32,7 +32,7 @@ public: void on_entry_start(uint8_t entry_number, Result::FileType file_type, uint64_t file_len, - nonstd::optional raw_file) override; + std::optional raw_file) override; void on_entry_data(const uint8_t* data, size_t size) override; void on_entry_end() override; diff --git a/src/ResultInspector.cpp b/src/ResultInspector.cpp index ba3151ec7..0c4753ce3 100644 --- a/src/ResultInspector.cpp +++ b/src/ResultInspector.cpp @@ -22,8 +22,6 @@ #include "Logging.hpp" #include "fmtmacros.hpp" -using nonstd::optional; - ResultInspector::ResultInspector(FILE* stream) : m_stream(stream) { } @@ -32,7 +30,7 @@ void ResultInspector::on_entry_start(uint8_t entry_number, Result::FileType file_type, uint64_t file_len, - optional raw_file) + std::optional raw_file) { PRINT(m_stream, "{} file #{}: {} ({} bytes)\n", diff --git a/src/ResultInspector.hpp b/src/ResultInspector.hpp index 10dad1c42..d2df8ae24 100644 --- a/src/ResultInspector.hpp +++ b/src/ResultInspector.hpp @@ -32,7 +32,7 @@ public: void on_entry_start(uint8_t entry_number, Result::FileType file_type, uint64_t file_len, - nonstd::optional raw_file) override; + std::optional raw_file) override; void on_entry_data(const uint8_t* data, size_t size) override; void on_entry_end() override; diff --git a/src/ResultRetriever.cpp b/src/ResultRetriever.cpp index fc2323be3..c1c584ebc 100644 --- a/src/ResultRetriever.cpp +++ b/src/ResultRetriever.cpp @@ -45,7 +45,7 @@ void ResultRetriever::on_entry_start(uint8_t entry_number, FileType file_type, uint64_t file_len, - nonstd::optional raw_file) + std::optional raw_file) { LOG("Reading {} entry #{} {} ({} bytes)", raw_file ? "raw" : "embedded", diff --git a/src/ResultRetriever.hpp b/src/ResultRetriever.hpp index 98f0b9111..27c13f9b3 100644 --- a/src/ResultRetriever.hpp +++ b/src/ResultRetriever.hpp @@ -32,7 +32,7 @@ public: void on_entry_start(uint8_t entry_number, Result::FileType file_type, uint64_t file_len, - nonstd::optional raw_file) override; + std::optional raw_file) override; void on_entry_data(const uint8_t* data, size_t size) override; void on_entry_end() override; diff --git a/src/UmaskScope.hpp b/src/UmaskScope.hpp index 67338e5a7..e71eb0a75 100644 --- a/src/UmaskScope.hpp +++ b/src/UmaskScope.hpp @@ -18,24 +18,24 @@ #pragma once -#include "third_party/nonstd/optional.hpp" - #include #include +#include + // This class sets a new (process-global) umask and restores the previous umask // when destructed. class UmaskScope { public: - UmaskScope(nonstd::optional new_umask); + UmaskScope(std::optional new_umask); ~UmaskScope(); private: - nonstd::optional m_saved_umask; + std::optional m_saved_umask = std::nullopt; }; -inline UmaskScope::UmaskScope(nonstd::optional new_umask) +inline UmaskScope::UmaskScope(std::optional new_umask) { #ifndef _WIN32 if (new_umask) { diff --git a/src/Util.cpp b/src/Util.cpp index abbf76d3e..d39b74667 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -100,8 +100,6 @@ extern "C" { # endif #endif -using nonstd::nullopt; -using nonstd::optional; using nonstd::string_view; using IncludeDelimiter = util::Tokenizer::IncludeDelimiter; @@ -786,7 +784,7 @@ hard_link(const std::string& oldpath, const std::string& newpath) #endif } -nonstd::optional +std::optional is_absolute_path_with_prefix(nonstd::string_view path) { #ifdef _WIN32 @@ -808,7 +806,7 @@ is_absolute_path_with_prefix(nonstd::string_view path) // NOLINTNEXTLINE(readability-simplify-boolean-expr) return split_pos; } - return nonstd::nullopt; + return std::nullopt; } #if defined(HAVE_LINUX_FS_H) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) @@ -842,15 +840,15 @@ is_precompiled_header(string_view path) || get_extension(dir_name(path)) == ".gch"; } -optional -localtime(optional time) +std::optional +localtime(std::optional time) { time_t timestamp = time ? *time : ::time(nullptr); tm result; if (localtime_r(×tamp, &result)) { return result; } else { - return nullopt; + return std::nullopt; } } diff --git a/src/Util.hpp b/src/Util.hpp index 4ddffa346..1502af4ef 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -21,7 +21,6 @@ #include #include -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -227,7 +227,7 @@ int_to_big_endian(int8_t value, uint8_t* buffer) // Determine if `path` is an absolute path with prefix, returning the split // point. -nonstd::optional is_absolute_path_with_prefix(nonstd::string_view path); +std::optional is_absolute_path_with_prefix(nonstd::string_view path); // Test if a file is on nfs. // @@ -255,7 +255,7 @@ bool is_precompiled_header(nonstd::string_view path); // Thread-safe version of `localtime(3)`. If `time` is not specified the current // time of day is used. -nonstd::optional localtime(nonstd::optional time = {}); +std::optional localtime(std::optional time = {}); // Make a relative path from current working directory (either `actual_cwd` or // `apparent_cwd`) to `path` if `path` is under `base_dir`. diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index cc4040d72..90603af6c 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -35,8 +35,6 @@ #include using core::Statistic; -using nonstd::nullopt; -using nonstd::optional; using nonstd::string_view; namespace { @@ -56,7 +54,7 @@ struct ArgumentProcessingState ColorDiagnostics color_diagnostics = ColorDiagnostics::automatic; bool found_directives_only = false; bool found_rewrite_includes = false; - nonstd::optional found_xarch_arch; + std::optional found_xarch_arch; std::string explicit_language; // As specified with -x. std::string input_charset_option; // -finput-charset=... @@ -252,7 +250,7 @@ process_profiling_option(const Context& ctx, return true; } -optional +std::optional process_arg(const Context& ctx, ArgsInfo& args_info, Config& config, @@ -270,7 +268,7 @@ process_arg(const Context& ctx, return Statistic::bad_compiler_arguments; } state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } bool changed_from_slash = false; @@ -317,7 +315,7 @@ process_arg(const Context& ctx, args.replace(i, *file_args); i--; - return nullopt; + return std::nullopt; } // Handle cuda "-optf" and "--options-file" argument. @@ -341,7 +339,7 @@ process_arg(const Context& ctx, args.insert(i + 1, *file_args); } - return nullopt; + return std::nullopt; } // These are always too hard. @@ -374,7 +372,7 @@ process_arg(const Context& ctx, state.common_args.push_back(args[i]); state.common_args.push_back(args[i + 1]); ++i; - return nullopt; + return std::nullopt; } // Handle -arch options. @@ -384,7 +382,7 @@ process_arg(const Context& ctx, if (args_info.arch_args.size() == 2) { config.set_run_second_cpp(true); } - return nullopt; + return std::nullopt; } // Some arguments that clang passes directly to cc1 (related to precompiled @@ -417,11 +415,11 @@ process_arg(const Context& ctx, state.compiler_only_args.push_back(args[i + 1]); ++i; } - return nullopt; + return std::nullopt; } if (compopt_prefix_affects_compiler_output(args[i])) { state.compiler_only_args.push_back(args[i]); - return nullopt; + return std::nullopt; } // Modules are handled on demand as necessary in the background, so there is @@ -448,28 +446,28 @@ process_arg(const Context& ctx, // We must have -c. if (args[i] == "-c") { state.found_c_opt = true; - return nullopt; + return std::nullopt; } // MSVC -Fo with no space. if (util::starts_with(args[i], "-Fo") && config.is_compiler_group_msvc()) { args_info.output_obj = Util::make_relative_path(ctx, string_view(args[i]).substr(3)); - return nullopt; + return std::nullopt; } // when using nvcc with separable compilation, -dc implies -c if ((args[i] == "-dc" || args[i] == "--device-c") && config.compiler_type() == CompilerType::nvcc) { state.found_dc_opt = true; - return nullopt; + return std::nullopt; } // -S changes the default extension. if (args[i] == "-S") { state.common_args.push_back(args[i]); state.found_S_opt = true; - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-x")) { @@ -479,7 +477,7 @@ process_arg(const Context& ctx, // language specification. (GCC's "-x" language argument is always // lowercase.) state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } // Special handling for -x: remember the last specified language before the @@ -493,14 +491,14 @@ process_arg(const Context& ctx, state.explicit_language = args[i + 1]; } i++; - return nullopt; + return std::nullopt; } DEBUG_ASSERT(args[i].length() >= 3); if (args_info.input_file.empty()) { state.explicit_language = args[i].substr(2); } - return nullopt; + return std::nullopt; } // We need to work out where the output was meant to go. @@ -511,7 +509,7 @@ process_arg(const Context& ctx, } args_info.output_obj = Util::make_relative_path(ctx, args[i + 1]); i++; - return nullopt; + return std::nullopt; } // Alternate form of -o with no space. Nvcc does not support this. @@ -523,7 +521,7 @@ process_arg(const Context& ctx, && config.compiler_type() != CompilerType::msvc) { args_info.output_obj = Util::make_relative_path(ctx, string_view(args[i]).substr(2)); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-fdebug-prefix-map=") @@ -531,7 +529,7 @@ process_arg(const Context& ctx, std::string map = args[i].substr(args[i].find('=') + 1); args_info.debug_prefix_maps.push_back(map); state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } // Debugging is handled specially, so that we know if we can strip line @@ -543,12 +541,12 @@ process_arg(const Context& ctx, // Selection of DWARF format (-gdwarf or -gdwarf-) enables // debug info on level 2. args_info.generating_debuginfo = true; - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-gz")) { // -gz[=type] neither disables nor enables debug info. - return nullopt; + return std::nullopt; } char last_char = args[i].back(); @@ -565,7 +563,7 @@ process_arg(const Context& ctx, args_info.seen_split_dwarf = true; } } - return nullopt; + return std::nullopt; } // These options require special handling, because they behave differently @@ -575,7 +573,7 @@ process_arg(const Context& ctx, args_info.generating_dependencies = true; args_info.seen_MD_MMD = true; state.dep_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-MF")) { @@ -603,7 +601,7 @@ process_arg(const Context& ctx, } else { state.dep_args.push_back("-MF" + args_info.output_dep); } - return nullopt; + return std::nullopt; } if ((util::starts_with(args[i], "-MQ") || util::starts_with(args[i], "-MT")) @@ -626,7 +624,7 @@ process_arg(const Context& ctx, auto relpath = Util::make_relative_path(ctx, option); state.dep_args.push_back(FMT("{}{}", arg_opt, relpath)); } - return nullopt; + return std::nullopt; } // MSVC -MD[d], -MT[d] and -LT[d] options are something different than GCC's @@ -637,25 +635,25 @@ process_arg(const Context& ctx, // These affect compiler but also #define some things. state.cpp_args.push_back(args[i]); state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-fprofile-arcs") { args_info.profile_arcs = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-ftest-coverage") { args_info.generating_coverage = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-fstack-usage") { args_info.generating_stackusage = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } // -Zs is MSVC's -fsyntax-only equivalent @@ -663,7 +661,7 @@ process_arg(const Context& ctx, args_info.expect_output_obj = false; state.compiler_only_args.push_back(args[i]); state.found_syntax_only = true; - return nullopt; + return std::nullopt; } if (args[i] == "--coverage" // = -fprofile-arcs -ftest-coverage @@ -671,7 +669,7 @@ process_arg(const Context& ctx, args_info.profile_arcs = true; args_info.generating_coverage = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-fprofile-") @@ -682,20 +680,20 @@ process_arg(const Context& ctx, return Statistic::unsupported_compiler_option; } state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-fsanitize-blacklist=")) { args_info.sanitize_blacklists.emplace_back(args[i].substr(21)); state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "--sysroot=")) { auto path = string_view(args[i]).substr(10); auto relpath = Util::make_relative_path(ctx, path); state.common_args.push_back("--sysroot=" + relpath); - return nullopt; + return std::nullopt; } // Alternate form of specifying sysroot without = @@ -708,7 +706,7 @@ process_arg(const Context& ctx, auto relpath = Util::make_relative_path(ctx, args[i + 1]); state.common_args.push_back(relpath); i++; - return nullopt; + return std::nullopt; } // Alternate form of specifying target without = @@ -720,7 +718,7 @@ process_arg(const Context& ctx, state.common_args.push_back(args[i]); state.common_args.push_back(args[i + 1]); i++; - return nullopt; + return std::nullopt; } if (args[i] == "-P" || args[i] == "-Wp,-P") { @@ -729,7 +727,7 @@ process_arg(const Context& ctx, state.compiler_only_args.push_back(args[i]); LOG("{} used; not compiling preprocessed code", args[i]); config.set_run_second_cpp(true); - return nullopt; + return std::nullopt; } if (util::starts_with(args[i], "-Wp,")) { @@ -744,7 +742,7 @@ process_arg(const Context& ctx, args_info.output_dep = Util::make_relative_path(ctx, string_view(args[i]).substr(8)); state.dep_args.push_back(args[i]); - return nullopt; + return std::nullopt; } else if (util::starts_with(args[i], "-Wp,-MMD,") && args[i].find(',', 9) == std::string::npos) { args_info.generating_dependencies = true; @@ -752,12 +750,12 @@ process_arg(const Context& ctx, args_info.output_dep = Util::make_relative_path(ctx, string_view(args[i]).substr(9)); state.dep_args.push_back(args[i]); - return nullopt; + return std::nullopt; } else if (util::starts_with(args[i], "-Wp,-D") && args[i].find(',', 6) == std::string::npos) { // Treat it like -D. state.cpp_args.push_back(args[i].substr(4)); - return nullopt; + return std::nullopt; } else if (args[i] == "-Wp,-MP" || (args[i].size() > 8 && util::starts_with(args[i], "-Wp,-M") && args[i][7] == ',' @@ -766,7 +764,7 @@ process_arg(const Context& ctx, && args[i].find(',', 8) == std::string::npos)) { // TODO: Make argument to MF/MQ/MT relative. state.dep_args.push_back(args[i]); - return nullopt; + return std::nullopt; } else if (config.direct_mode()) { // -Wp, can be used to pass too hard options to the preprocessor. // Hence, disable direct mode. @@ -776,18 +774,18 @@ process_arg(const Context& ctx, // Any other -Wp,* arguments are only relevant for the preprocessor. state.cpp_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-MP") { state.dep_args.push_back(args[i]); - return nullopt; + return std::nullopt; } // Input charset needs to be handled specially. if (util::starts_with(args[i], "-finput-charset=")) { state.input_charset_option = args[i]; - return nullopt; + return std::nullopt; } if (args[i] == "--serialize-diagnostics") { @@ -798,7 +796,7 @@ process_arg(const Context& ctx, args_info.generating_diagnostics = true; args_info.output_dia = Util::make_relative_path(ctx, args[i + 1]); i++; - return nullopt; + return std::nullopt; } if (config.compiler_type() == CompilerType::gcc @@ -826,42 +824,42 @@ process_arg(const Context& ctx, || args[i] == "-fdiagnostics-color=always") { state.color_diagnostics = ColorDiagnostics::always; state.compiler_only_args_no_hash.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-fno-color-diagnostics" || args[i] == "-fno-diagnostics-color" || args[i] == "-fdiagnostics-color=never") { state.color_diagnostics = ColorDiagnostics::never; state.compiler_only_args_no_hash.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-fdiagnostics-color=auto") { state.color_diagnostics = ColorDiagnostics::automatic; state.compiler_only_args_no_hash.push_back(args[i]); - return nullopt; + return std::nullopt; } // GCC if (args[i] == "-fdirectives-only") { state.found_directives_only = true; - return nullopt; + return std::nullopt; } // Clang if (args[i] == "-frewrite-includes") { state.found_rewrite_includes = true; - return nullopt; + return std::nullopt; } if (args[i] == "-fno-pch-timestamp") { args_info.fno_pch_timestamp = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (args[i] == "-fpch-preprocess") { state.found_fpch_preprocess = true; state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (config.sloppiness().is_enabled(core::Sloppy::clang_index_store) @@ -873,7 +871,7 @@ process_arg(const Context& ctx, if (i <= args.size() - 1) { LOG("Skipping argument -index-store-path {}", args[i]); } - return nullopt; + return std::nullopt; } if (args[i] == "-frecord-gcc-switches") { @@ -883,7 +881,7 @@ process_arg(const Context& ctx, // MSVC -u is something else than GCC -u, handle it specially. if (args[i] == "-u" && ctx.config.is_compiler_group_msvc()) { state.cpp_args.push_back(args[i]); - return nullopt; + return std::nullopt; } if (compopt_takes_path(args[i])) { @@ -917,7 +915,7 @@ process_arg(const Context& ctx, dest_args.push_back(relpath); i += next; - return nullopt; + return std::nullopt; } // Detect PCH for options with concatenated path (relative or absolute). @@ -948,7 +946,7 @@ process_arg(const Context& ctx, } else { state.common_args.push_back(new_option); } - return nullopt; + return std::nullopt; } } } @@ -969,7 +967,7 @@ process_arg(const Context& ctx, } i++; - return nullopt; + return std::nullopt; } // Other options. @@ -980,7 +978,7 @@ process_arg(const Context& ctx, } else { state.common_args.push_back(args[i]); } - return nullopt; + return std::nullopt; } // It was not a known option. @@ -998,7 +996,7 @@ process_arg(const Context& ctx, if (!st || !st.is_regular()) { LOG("{} is not a regular file, not considering as input file", args[i]); state.common_args.push_back(args[i]); - return nullopt; + return std::nullopt; } } @@ -1024,7 +1022,7 @@ process_arg(const Context& ctx, args_info.normalized_input_file = Util::normalize_concrete_absolute_path(args_info.input_file); - return nullopt; + return std::nullopt; } void @@ -1101,7 +1099,7 @@ process_args(Context& ctx) state.common_args.push_back(args[0]); // Compiler - optional argument_error; + std::optional argument_error; for (size_t i = 1; i < args.size(); i++) { const auto error = process_arg(ctx, ctx.args_info, ctx.config, args, i, state); @@ -1309,7 +1307,7 @@ process_args(Context& ctx) // Since output is redirected, compilers will not color their output by // default, so force it explicitly. - nonstd::optional diagnostics_color_arg; + std::optional diagnostics_color_arg; if (config.is_compiler_group_clang()) { // Don't pass -fcolor-diagnostics when compiling assembler to avoid an // "argument unused during compilation" warning. diff --git a/src/argprocessing.hpp b/src/argprocessing.hpp index 54671e8f9..474a648e7 100644 --- a/src/argprocessing.hpp +++ b/src/argprocessing.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Joel Rosdahl and other contributors +// Copyright (C) 2020-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -22,7 +22,7 @@ #include -#include "third_party/nonstd/optional.hpp" +#include class Context; @@ -35,7 +35,7 @@ struct ProcessArgsResult // nullopt on success, otherwise the statistics counter that should be // incremented. - nonstd::optional error; + std::optional error; // Arguments (except -E) to send to the preprocessor. Args preprocessor_args; diff --git a/src/ccache.cpp b/src/ccache.cpp index b0c27d064..edff616da 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -64,11 +64,12 @@ #include #include "third_party/fmt/core.h" -#include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" #include +#include + #ifdef HAVE_UNISTD_H # include #endif @@ -84,8 +85,6 @@ const char CCACHE_NAME[] = MYNAME; using core::Statistic; -using nonstd::nullopt; -using nonstd::optional; using nonstd::string_view; // This is a string that identifies the current "version" of the hash sum @@ -108,12 +107,12 @@ public: Failure(std::initializer_list statistics); const core::StatisticsCounters& counters() const; - nonstd::optional exit_code() const; + std::optional exit_code() const; void set_exit_code(int exit_code); private: core::StatisticsCounters m_counters; - nonstd::optional m_exit_code; + std::optional m_exit_code; }; inline Failure::Failure(const Statistic statistic) : m_counters({statistic}) @@ -131,7 +130,7 @@ Failure::counters() const return m_counters; } -inline nonstd::optional +inline std::optional Failure::exit_code() const { return m_exit_code; @@ -622,7 +621,7 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path) // Extract the used includes from the dependency file. Note that we cannot // distinguish system headers from other includes here. -static optional +static std::optional result_key_from_depfile(Context& ctx, Hash& hash) { std::string file_content; @@ -631,7 +630,7 @@ result_key_from_depfile(Context& ctx, Hash& hash) } catch (const core::Error& e) { LOG( "Cannot open dependency file {}: {}", ctx.args_info.output_dep, e.what()); - return nullopt; + return std::nullopt; } for (string_view token : Depfile::tokenize(file_content)) { @@ -939,7 +938,7 @@ rewrite_stdout_from_compiler(const Context& ctx, std::string&& stdout_data) static nonstd::expected to_cache(Context& ctx, Args& args, - nonstd::optional result_key, + std::optional result_key, const Args& depend_extra_args, Hash* depend_mode_hash) { @@ -1514,9 +1513,8 @@ option_should_be_ignored(const std::string& arg, // Update a hash sum with information specific to the direct and preprocessor // modes and calculate the result key. Returns the result key on success, and // if direct_mode is true also the manifest key. -static nonstd::expected< - std::pair, nonstd::optional>, - Failure> +static nonstd::expected, std::optional>, + Failure> calculate_result_and_manifest_key(Context& ctx, const Args& args, Args& preprocessor_args, @@ -1748,8 +1746,8 @@ calculate_result_and_manifest_key(Context& ctx, hash.hash(arch); } - nonstd::optional result_key; - nonstd::optional manifest_key; + std::optional result_key; + std::optional manifest_key; if (direct_mode) { // Hash environment variables that affect the preprocessor output. @@ -1789,7 +1787,7 @@ calculate_result_and_manifest_key(Context& ctx, if (result & HASH_SOURCE_CODE_FOUND_TIME) { LOG_RAW("Disabling direct mode"); ctx.config.set_direct_mode(false); - return std::make_pair(nullopt, nullopt); + return std::make_pair(std::nullopt, std::nullopt); } manifest_key = hash.digest(); @@ -1832,7 +1830,7 @@ calculate_result_and_manifest_key(Context& ctx, LOG("Got result key from preprocessor with -arch {}", ctx.args_info.arch_args[i]); if (i != ctx.args_info.arch_args.size() - 1) { - result_key = nullopt; + result_key = std::nullopt; } preprocessor_args.pop_back(); } @@ -2047,7 +2045,7 @@ cache_compilation(int argc, const char* const* argv) bool fall_back_to_original_compiler = false; Args saved_orig_args; - nonstd::optional original_umask; + std::optional original_umask; std::string saved_temp_dir; { @@ -2240,9 +2238,9 @@ do_cache_compilation(Context& ctx, const char* const* argv) args_to_hash.push_back(processed.extra_args_to_hash); bool put_result_in_manifest = false; - optional result_key; - optional result_key_from_manifest; - optional manifest_key; + std::optional result_key; + std::optional result_key_from_manifest; + std::optional manifest_key; if (ctx.config.direct_mode()) { LOG_RAW("Trying direct lookup"); diff --git a/src/core/Manifest.cpp b/src/core/Manifest.cpp index f9301e46c..64b6b85a3 100644 --- a/src/core/Manifest.cpp +++ b/src/core/Manifest.cpp @@ -119,7 +119,7 @@ Manifest::read(Reader& reader) } } -nonstd::optional +std::optional Manifest::look_up_result_digest(const Context& ctx) const { std::unordered_map stated_files; @@ -133,7 +133,7 @@ Manifest::look_up_result_digest(const Context& ctx) const } } - return nonstd::nullopt; + return std::nullopt; } bool diff --git a/src/core/Manifest.hpp b/src/core/Manifest.hpp index 78c16a64b..ace63be83 100644 --- a/src/core/Manifest.hpp +++ b/src/core/Manifest.hpp @@ -20,9 +20,8 @@ #include -#include - #include +#include #include #include #include @@ -42,7 +41,7 @@ public: Manifest() = default; void read(Reader& reader); - nonstd::optional look_up_result_digest(const Context& ctx) const; + std::optional look_up_result_digest(const Context& ctx) const; bool add_result(const Digest& result_key, const std::unordered_map& included_files, diff --git a/src/core/exceptions.hpp b/src/core/exceptions.hpp index aae4b26e0..95176d7ca 100644 --- a/src/core/exceptions.hpp +++ b/src/core/exceptions.hpp @@ -21,8 +21,8 @@ #include #include -#include +#include #include #include #include diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index 27431f9ae..73d5c054a 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -42,10 +42,9 @@ #include #include -#include - #include +#include #include #ifdef HAVE_UNISTD_H @@ -349,11 +348,11 @@ int process_main_options(int argc, const char* const* argv) { int c; - nonstd::optional trim_max_size; + std::optional trim_max_size; bool trim_lru_mtime = false; uint8_t verbosity = 0; - nonstd::optional evict_namespace; - nonstd::optional evict_max_age; + std::optional evict_namespace; + std::optional evict_max_age; // First pass: Handle non-command options that affect command options. while ((c = getopt_long(argc, @@ -604,9 +603,9 @@ process_main_options(int argc, const char* const* argv) case 'X': // --recompress { - nonstd::optional wanted_level; + std::optional wanted_level; if (arg == "uncompressed") { - wanted_level = nonstd::nullopt; + wanted_level = std::nullopt; } else { wanted_level = util::value_or_throw( util::parse_signed(arg, INT8_MIN, INT8_MAX, "compression level")); diff --git a/src/storage/Storage.cpp b/src/storage/Storage.cpp index 098807779..cc56beff5 100644 --- a/src/storage/Storage.cpp +++ b/src/storage/Storage.cpp @@ -227,7 +227,7 @@ Storage::finalize() primary.finalize(); } -nonstd::optional +std::optional Storage::get(const Digest& key, const core::CacheEntryType type) { MTR_SCOPE("storage", "get"); @@ -260,7 +260,7 @@ Storage::get(const Digest& key, const core::CacheEntryType type) const auto value_and_share_hits = get_from_secondary_storage(key); if (!value_and_share_hits) { - return nonstd::nullopt; + return std::nullopt; } const auto& value = value_and_share_hits->first; const auto& share_hits = value_and_share_hits->second; @@ -464,7 +464,7 @@ Storage::get_backend(SecondaryStorageEntry& entry, } } -nonstd::optional> +std::optional> Storage::get_from_secondary_storage(const Digest& key) { MTR_SCOPE("secondary_storage", "get"); @@ -500,7 +500,7 @@ Storage::get_from_secondary_storage(const Digest& key) } } - return nonstd::nullopt; + return std::nullopt; } void diff --git a/src/storage/Storage.hpp b/src/storage/Storage.hpp index 2b245d1a1..ab41c86e5 100644 --- a/src/storage/Storage.hpp +++ b/src/storage/Storage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -23,10 +23,9 @@ #include #include -#include - #include #include +#include #include #include #include @@ -52,8 +51,7 @@ public: primary::PrimaryStorage primary; // Returns a path to a file containing the value. - nonstd::optional get(const Digest& key, - core::CacheEntryType type); + std::optional get(const Digest& key, core::CacheEntryType type); bool put(const Digest& key, core::CacheEntryType type, @@ -80,7 +78,7 @@ private: const Digest& key, nonstd::string_view operation_description, const bool for_writing); - nonstd::optional> + std::optional> get_from_secondary_storage(const Digest& key); void put_in_secondary_storage(const Digest& key, diff --git a/src/storage/primary/CacheFile.hpp b/src/storage/primary/CacheFile.hpp index 809ea38a4..e653363bf 100644 --- a/src/storage/primary/CacheFile.hpp +++ b/src/storage/primary/CacheFile.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2021 Joel Rosdahl and other contributors +// Copyright (C) 2019-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -20,8 +20,7 @@ #include -#include - +#include #include class CacheFile @@ -37,7 +36,7 @@ public: private: std::string m_path; - mutable nonstd::optional m_stat; + mutable std::optional m_stat; }; inline CacheFile::CacheFile(const std::string& path) : m_path(path) diff --git a/src/storage/primary/PrimaryStorage.cpp b/src/storage/primary/PrimaryStorage.cpp index a4280b345..c4e058170 100644 --- a/src/storage/primary/PrimaryStorage.cpp +++ b/src/storage/primary/PrimaryStorage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -176,13 +176,13 @@ PrimaryStorage::finalize() clean_dir(subdir, max_size, max_files, - nonstd::nullopt, - nonstd::nullopt, + std::nullopt, + std::nullopt, [](double /*progress*/) {}); } } -nonstd::optional +std::optional PrimaryStorage::get(const Digest& key, const core::CacheEntryType type) const { MTR_SCOPE("primary_storage", "get"); @@ -190,7 +190,7 @@ PrimaryStorage::get(const Digest& key, const core::CacheEntryType type) const const auto cache_file = look_up_cache_file(key, type); if (!cache_file.stat) { LOG("No {} in primary storage", key.to_string()); - return nonstd::nullopt; + return std::nullopt; } LOG( @@ -201,7 +201,7 @@ PrimaryStorage::get(const Digest& key, const core::CacheEntryType type) const return cache_file.path; } -nonstd::optional +std::optional PrimaryStorage::put(const Digest& key, const core::CacheEntryType type, const storage::EntryWriter& entry_writer) @@ -223,13 +223,13 @@ PrimaryStorage::put(const Digest& key, if (!entry_writer(cache_file.path)) { LOG("Did not store {} in primary storage", key.to_string()); - return nonstd::nullopt; + return std::nullopt; } const auto new_stat = Stat::stat(cache_file.path, Stat::OnError::log); if (!new_stat) { LOG("Failed to stat {}: {}", cache_file.path, strerror(errno)); - return nonstd::nullopt; + return std::nullopt; } LOG("Stored {} in primary storage ({})", key.to_string(), cache_file.path); @@ -329,7 +329,7 @@ PrimaryStorage::clean_internal_tempdir() }); } -nonstd::optional +std::optional PrimaryStorage::update_stats_and_maybe_move_cache_file( const Digest& key, const std::string& current_path, @@ -337,7 +337,7 @@ PrimaryStorage::update_stats_and_maybe_move_cache_file( const core::CacheEntryType type) { if (counter_updates.all_zero()) { - return nonstd::nullopt; + return std::nullopt; } // Use stats file in the level one subdirectory for cache bookkeeping counters @@ -358,7 +358,7 @@ PrimaryStorage::update_stats_and_maybe_move_cache_file( cs.increment(counter_updates); }); if (!counters) { - return nonstd::nullopt; + return std::nullopt; } if (use_stats_on_level_1) { diff --git a/src/storage/primary/PrimaryStorage.hpp b/src/storage/primary/PrimaryStorage.hpp index bb8b50545..babb7d79b 100644 --- a/src/storage/primary/PrimaryStorage.hpp +++ b/src/storage/primary/PrimaryStorage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -24,9 +24,8 @@ #include #include -#include - #include +#include class Config; @@ -52,12 +51,12 @@ public: // --- Cache entry handling --- // Returns a path to a file containing the value. - nonstd::optional get(const Digest& key, - core::CacheEntryType type) const; + std::optional get(const Digest& key, + core::CacheEntryType type) const; - nonstd::optional put(const Digest& key, - core::CacheEntryType type, - const storage::EntryWriter& entry_writer); + std::optional put(const Digest& key, + core::CacheEntryType type, + const storage::EntryWriter& entry_writer); void remove(const Digest& key, core::CacheEntryType type); @@ -78,8 +77,8 @@ public: // --- Cleanup --- void evict(const ProgressReceiver& progress_receiver, - nonstd::optional max_age, - nonstd::optional namespace_); + std::optional max_age, + std::optional namespace_); void clean_all(const ProgressReceiver& progress_receiver); @@ -90,7 +89,7 @@ public: CompressionStatistics get_compression_statistics(const ProgressReceiver& progress_receiver) const; - void recompress(nonstd::optional level, + void recompress(std::optional level, const ProgressReceiver& progress_receiver); private: @@ -107,8 +106,8 @@ private: // The manifest and result keys and paths are stored by put() so that // finalize() can use them to move the files in place. - nonstd::optional m_manifest_key; - nonstd::optional m_result_key; + std::optional m_manifest_key; + std::optional m_result_key; std::string m_manifest_path; std::string m_result_path; @@ -124,7 +123,7 @@ private: void clean_internal_tempdir(); - nonstd::optional + std::optional update_stats_and_maybe_move_cache_file( const Digest& key, const std::string& current_path, @@ -139,8 +138,8 @@ private: static void clean_dir(const std::string& subdir, uint64_t max_size, uint64_t max_files, - nonstd::optional max_age, - nonstd::optional namespace_, + std::optional max_age, + std::optional namespace_, const ProgressReceiver& progress_receiver); }; diff --git a/src/storage/primary/PrimaryStorage_cleanup.cpp b/src/storage/primary/PrimaryStorage_cleanup.cpp index 63b956ac4..e07e44aee 100644 --- a/src/storage/primary/PrimaryStorage_cleanup.cpp +++ b/src/storage/primary/PrimaryStorage_cleanup.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2002-2006 Andrew Tridgell -// Copyright (C) 2009-2021 Joel Rosdahl and other contributors +// Copyright (C) 2009-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -80,8 +80,8 @@ update_counters(const std::string& dir, void PrimaryStorage::evict(const ProgressReceiver& progress_receiver, - nonstd::optional max_age, - nonstd::optional namespace_) + std::optional max_age, + std::optional namespace_) { for_each_level_1_subdir( m_config.cache_dir(), @@ -97,8 +97,8 @@ void PrimaryStorage::clean_dir(const std::string& subdir, const uint64_t max_size, const uint64_t max_files, - const nonstd::optional max_age, - const nonstd::optional namespace_, + const std::optional max_age, + const std::optional namespace_, const ProgressReceiver& progress_receiver) { LOG("Cleaning up cache directory {}", subdir); @@ -243,8 +243,8 @@ PrimaryStorage::clean_all(const ProgressReceiver& progress_receiver) clean_dir(subdir, m_config.max_size() / 16, m_config.max_files() / 16, - nonstd::nullopt, - nonstd::nullopt, + std::nullopt, + std::nullopt, sub_progress_receiver); }, progress_receiver); diff --git a/src/storage/primary/PrimaryStorage_compress.cpp b/src/storage/primary/PrimaryStorage_compress.cpp index 4965f224c..d4a78319b 100644 --- a/src/storage/primary/PrimaryStorage_compress.cpp +++ b/src/storage/primary/PrimaryStorage_compress.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2021 Joel Rosdahl and other contributors +// Copyright (C) 2019-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -146,7 +146,7 @@ static void recompress_file(RecompressionStatistics& statistics, const std::string& stats_file, const CacheFile& cache_file, - const nonstd::optional level) + const std::optional level) { auto file = open_file(cache_file.path(), "rb"); core::FileReader file_reader(file.get()); @@ -237,7 +237,7 @@ PrimaryStorage::get_compression_statistics( } void -PrimaryStorage::recompress(const nonstd::optional level, +PrimaryStorage::recompress(const std::optional level, const ProgressReceiver& progress_receiver) { const size_t threads = std::thread::hardware_concurrency(); diff --git a/src/storage/primary/StatsFile.cpp b/src/storage/primary/StatsFile.cpp index 87f0f881f..b2a248e80 100644 --- a/src/storage/primary/StatsFile.cpp +++ b/src/storage/primary/StatsFile.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -61,14 +61,14 @@ StatsFile::read() const return counters; } -nonstd::optional +std::optional StatsFile::update( std::function function) const { Lockfile lock(m_path); if (!lock.acquired()) { LOG("Failed to acquire lock for {}", m_path); - return nonstd::nullopt; + return std::nullopt; } auto counters = read(); diff --git a/src/storage/primary/StatsFile.hpp b/src/storage/primary/StatsFile.hpp index 0b8b96d4d..0a8eaaa62 100644 --- a/src/storage/primary/StatsFile.hpp +++ b/src/storage/primary/StatsFile.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -20,9 +20,8 @@ #include -#include - #include +#include #include namespace storage { @@ -40,7 +39,7 @@ public: // Acquire a lock, read counters, call `function` with the counters, write the // counters and release the lock. Returns the resulting counters or nullopt on // error (e.g. if the lock could not be acquired). - nonstd::optional + std::optional update(std::function) const; private: diff --git a/src/storage/secondary/FileStorage.cpp b/src/storage/secondary/FileStorage.cpp index c824604cb..906127d76 100644 --- a/src/storage/secondary/FileStorage.cpp +++ b/src/storage/secondary/FileStorage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -44,7 +44,7 @@ class FileStorageBackend : public SecondaryStorage::Backend public: FileStorageBackend(const Params& params); - nonstd::expected, Failure> + nonstd::expected, Failure> get(const Digest& key) override; nonstd::expected put(const Digest& key, @@ -57,7 +57,7 @@ private: enum class Layout { flat, subdirs }; const std::string m_dir; - nonstd::optional m_umask; + std::optional m_umask; bool m_update_mtime = false; Layout m_layout = Layout::subdirs; @@ -95,8 +95,7 @@ FileStorageBackend::FileStorageBackend(const Params& params) } } -nonstd::expected, - SecondaryStorage::Backend::Failure> +nonstd::expected, SecondaryStorage::Backend::Failure> FileStorageBackend::get(const Digest& key) { const auto path = get_entry_path(key); @@ -104,7 +103,7 @@ FileStorageBackend::get(const Digest& key) if (!exists) { // Don't log failure if the entry doesn't exist. - return nonstd::nullopt; + return std::nullopt; } if (m_update_mtime) { diff --git a/src/storage/secondary/HttpStorage.cpp b/src/storage/secondary/HttpStorage.cpp index 57d906f63..2c253a11b 100644 --- a/src/storage/secondary/HttpStorage.cpp +++ b/src/storage/secondary/HttpStorage.cpp @@ -40,7 +40,7 @@ class HttpStorageBackend : public SecondaryStorage::Backend public: HttpStorageBackend(const Params& params); - nonstd::expected, Failure> + nonstd::expected, Failure> get(const Digest& key) override; nonstd::expected put(const Digest& key, @@ -144,8 +144,7 @@ HttpStorageBackend::HttpStorageBackend(const Params& params) m_http_client.set_write_timeout(operation_timeout); } -nonstd::expected, - SecondaryStorage::Backend::Failure> +nonstd::expected, SecondaryStorage::Backend::Failure> HttpStorageBackend::get(const Digest& key) { const auto url_path = get_entry_path(key); @@ -161,7 +160,7 @@ HttpStorageBackend::get(const Digest& key) if (result->status < 200 || result->status >= 300) { // Don't log failure if the entry doesn't exist. - return nonstd::nullopt; + return std::nullopt; } return result->body; diff --git a/src/storage/secondary/RedisStorage.cpp b/src/storage/secondary/RedisStorage.cpp index 32bc4ae39..b76622d46 100644 --- a/src/storage/secondary/RedisStorage.cpp +++ b/src/storage/secondary/RedisStorage.cpp @@ -60,7 +60,7 @@ class RedisStorageBackend : public SecondaryStorage::Backend public: RedisStorageBackend(const SecondaryStorage::Backend::Params& params); - nonstd::expected, Failure> + nonstd::expected, Failure> get(const Digest& key) override; nonstd::expected put(const Digest& key, @@ -90,19 +90,19 @@ to_timeval(const uint32_t ms) return tv; } -std::pair, nonstd::optional> +std::pair, std::optional> split_user_info(const std::string& user_info) { const auto pair = util::split_once(user_info, ':'); if (pair.first.empty()) { // redis://HOST - return {nonstd::nullopt, nonstd::nullopt}; + return {std::nullopt, std::nullopt}; } else if (pair.second) { // redis://USERNAME:PASSWORD@HOST return {std::string(*pair.second), std::string(pair.first)}; } else { // redis://PASSWORD@HOST - return {std::string(pair.first), nonstd::nullopt}; + return {std::string(pair.first), std::nullopt}; } } @@ -149,8 +149,7 @@ is_timeout(int err) #endif } -nonstd::expected, - SecondaryStorage::Backend::Failure> +nonstd::expected, SecondaryStorage::Backend::Failure> RedisStorageBackend::get(const Digest& key) { const auto key_string = get_key_string(key); @@ -161,7 +160,7 @@ RedisStorageBackend::get(const Digest& key) } else if ((*reply)->type == REDIS_REPLY_STRING) { return std::string((*reply)->str, (*reply)->len); } else if ((*reply)->type == REDIS_REPLY_NIL) { - return nonstd::nullopt; + return std::nullopt; } else { LOG("Unknown reply type: {}", (*reply)->type); return nonstd::make_unexpected(Failure::error); diff --git a/src/storage/secondary/SecondaryStorage.hpp b/src/storage/secondary/SecondaryStorage.hpp index 628a9a748..7adea4777 100644 --- a/src/storage/secondary/SecondaryStorage.hpp +++ b/src/storage/secondary/SecondaryStorage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -21,11 +21,11 @@ #include #include -#include #include #include #include +#include #include #include @@ -78,8 +78,8 @@ public: virtual ~Backend() = default; // Get the value associated with `key`. Returns the value on success or - // nonstd::nullopt if the entry is not present. - virtual nonstd::expected, Failure> + // std::nullopt if the entry is not present. + virtual nonstd::expected, Failure> get(const Digest& key) = 0; // Put `value` associated to `key` in the storage. A true `only_if_missing` diff --git a/src/third_party/nonstd/optional.hpp b/src/third_party/nonstd/optional.hpp deleted file mode 100644 index 2c9f12242..000000000 --- a/src/third_party/nonstd/optional.hpp +++ /dev/null @@ -1,1807 +0,0 @@ -// -// Copyright (c) 2014-2021 Martin Moene -// -// https://github.com/martinmoene/optional-lite -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#pragma once - -#ifndef NONSTD_OPTIONAL_LITE_HPP -#define NONSTD_OPTIONAL_LITE_HPP - -#define optional_lite_MAJOR 3 -#define optional_lite_MINOR 5 -#define optional_lite_PATCH 0 - -#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) - -#define optional_STRINGIFY( x ) optional_STRINGIFY_( x ) -#define optional_STRINGIFY_( x ) #x - -// optional-lite configuration: - -#define optional_OPTIONAL_DEFAULT 0 -#define optional_OPTIONAL_NONSTD 1 -#define optional_OPTIONAL_STD 2 - -// tweak header support: - -#ifdef __has_include -# if __has_include() -# include -# endif -#define optional_HAVE_TWEAK_HEADER 1 -#else -#define optional_HAVE_TWEAK_HEADER 0 -//# pragma message("optional.hpp: Note: Tweak header not supported.") -#endif - -// optional selection and configuration: - -#if !defined( optional_CONFIG_SELECT_OPTIONAL ) -# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD ) -#endif - -// Control presence of exception handling (try and auto discover): - -#ifndef optional_CONFIG_NO_EXCEPTIONS -# if defined(_MSC_VER) -# include // for _HAS_EXCEPTIONS -# endif -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) -# define optional_CONFIG_NO_EXCEPTIONS 0 -# else -# define optional_CONFIG_NO_EXCEPTIONS 1 -# endif -#endif - -// C++ language version detection (C++20 is speculative): -// Note: VC14.0/1900 (VS2015) lacks too much from C++14. - -#ifndef optional_CPLUSPLUS -# if defined(_MSVC_LANG ) && !defined(__clang__) -# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) -# else -# define optional_CPLUSPLUS __cplusplus -# endif -#endif - -#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L ) -#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L ) -#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L ) -#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L ) -#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L ) -#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L ) - -// C++ language version (represent 98 as 3): - -#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) ) - -// Use C++17 std::optional if available and requested: - -#if optional_CPP17_OR_GREATER && defined(__has_include ) -# if __has_include( ) -# define optional_HAVE_STD_OPTIONAL 1 -# else -# define optional_HAVE_STD_OPTIONAL 0 -# endif -#else -# define optional_HAVE_STD_OPTIONAL 0 -#endif - -#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) ) - -// -// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite: -// - -#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES -#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 - -// C++17 std::in_place in : - -#if optional_CPP17_OR_GREATER - -#include - -namespace nonstd { - -using std::in_place; -using std::in_place_type; -using std::in_place_index; -using std::in_place_t; -using std::in_place_type_t; -using std::in_place_index_t; - -#define nonstd_lite_in_place_t( T) std::in_place_t -#define nonstd_lite_in_place_type_t( T) std::in_place_type_t -#define nonstd_lite_in_place_index_t(K) std::in_place_index_t - -#define nonstd_lite_in_place( T) std::in_place_t{} -#define nonstd_lite_in_place_type( T) std::in_place_type_t{} -#define nonstd_lite_in_place_index(K) std::in_place_index_t{} - -} // namespace nonstd - -#else // optional_CPP17_OR_GREATER - -#include - -namespace nonstd { -namespace detail { - -template< class T > -struct in_place_type_tag {}; - -template< std::size_t K > -struct in_place_index_tag {}; - -} // namespace detail - -struct in_place_t {}; - -template< class T > -inline in_place_t in_place( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -template< class T > -inline in_place_t in_place_type( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place_index( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -// mimic templated typedef: - -#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) - -#define nonstd_lite_in_place( T) nonstd::in_place_type -#define nonstd_lite_in_place_type( T) nonstd::in_place_type -#define nonstd_lite_in_place_index(K) nonstd::in_place_index - -} // namespace nonstd - -#endif // optional_CPP17_OR_GREATER -#endif // nonstd_lite_HAVE_IN_PLACE_TYPES - -// -// Using std::optional: -// - -#if optional_USES_STD_OPTIONAL - -#include - -namespace nonstd { - - using std::optional; - using std::bad_optional_access; - using std::hash; - - using std::nullopt; - using std::nullopt_t; - - using std::operator==; - using std::operator!=; - using std::operator<; - using std::operator<=; - using std::operator>; - using std::operator>=; - using std::make_optional; - using std::swap; -} - -#else // optional_USES_STD_OPTIONAL - -#include -#include - -// optional-lite alignment configuration: - -#ifndef optional_CONFIG_MAX_ALIGN_HACK -# define optional_CONFIG_MAX_ALIGN_HACK 0 -#endif - -#ifndef optional_CONFIG_ALIGN_AS -// no default, used in #if defined() -#endif - -#ifndef optional_CONFIG_ALIGN_AS_FALLBACK -# define optional_CONFIG_ALIGN_AS_FALLBACK double -#endif - -// Compiler warning suppression: - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wundef" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wundef" -#elif defined(_MSC_VER ) -# pragma warning( push ) -#endif - -// half-open range [lo..hi): -#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) - -// Compiler versions: -// -// MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) -// MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) -// MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) -// MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) -// MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) -// MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) -// MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) -// MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) -// MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) -// MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) -// MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) - -#if defined(_MSC_VER ) && !defined(__clang__) -# define optional_COMPILER_MSVC_VER (_MSC_VER ) -# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) -#else -# define optional_COMPILER_MSVC_VER 0 -# define optional_COMPILER_MSVC_VERSION 0 -#endif - -#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) ) - -#if defined(__GNUC__) && !defined(__clang__) -# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#else -# define optional_COMPILER_GNUC_VERSION 0 -#endif - -#if defined(__clang__) -# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -#else -# define optional_COMPILER_CLANG_VERSION 0 -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 ) -# pragma warning( disable: 4345 ) // initialization behavior changed -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 ) -# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' -#endif - -// Presence of language and library features: - -#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE ) - -#ifdef _HAS_CPP0X -# define optional_HAS_CPP0X _HAS_CPP0X -#else -# define optional_HAS_CPP0X 0 -#endif - -// Unless defined otherwise below, consider VC14 as C++11 for optional-lite: - -#if optional_COMPILER_MSVC_VER >= 1900 -# undef optional_CPP11_OR_GREATER -# define optional_CPP11_OR_GREATER 1 -#endif - -#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500) -#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600) -#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700) -#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800) -#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900) -#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910) - -#define optional_CPP14_000 (optional_CPP14_OR_GREATER) -#define optional_CPP17_000 (optional_CPP17_OR_GREATER) - -// clang >= 2.9, gcc >= 4.9, msvc >= vc14.0/1900 (vs15): -#define optional_CPP11_140_C290_G490 ((optional_CPP11_OR_GREATER_ && (optional_COMPILER_CLANG_VERSION >= 290 || optional_COMPILER_GNUC_VERSION >= 490)) || (optional_COMPILER_MSVC_VER >= 1900)) - -// clang >= 3.5, msvc >= vc11 (vs12): -#define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) ) - -// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12): -#define optional_CPP11_110_C350_G500 \ - ( optional_CPP11_110 && \ - !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \ - || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) ) - -// Presence of C++11 language features: - -#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140 -#define optional_HAVE_IS_DEFAULT optional_CPP11_140 -#define optional_HAVE_NOEXCEPT optional_CPP11_140 -#define optional_HAVE_NULLPTR optional_CPP11_100 -#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_C290_G490 -#define optional_HAVE_STATIC_ASSERT optional_CPP11_110 -#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140 - -// Presence of C++14 language features: - -#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000 - -// Presence of C++17 language features: - -#define optional_HAVE_NODISCARD optional_CPP17_000 - -// Presence of C++ library features: - -#define optional_HAVE_CONDITIONAL optional_CPP11_120 -#define optional_HAVE_REMOVE_CV optional_CPP11_120 -#define optional_HAVE_TYPE_TRAITS optional_CPP11_90 - -#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION ) -#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION ) - -#define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350 -#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 -#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350 -#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 -#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500 -#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500 - -// C++ feature usage: - -#if optional_HAVE( CONSTEXPR_11 ) -# define optional_constexpr constexpr -#else -# define optional_constexpr /*constexpr*/ -#endif - -#if optional_HAVE( IS_DEFAULT ) -# define optional_is_default = default; -#else -# define optional_is_default {} -#endif - -#if optional_HAVE( CONSTEXPR_14 ) -# define optional_constexpr14 constexpr -#else -# define optional_constexpr14 /*constexpr*/ -#endif - -#if optional_HAVE( NODISCARD ) -# define optional_nodiscard [[nodiscard]] -#else -# define optional_nodiscard /*[[nodiscard]]*/ -#endif - -#if optional_HAVE( NOEXCEPT ) -# define optional_noexcept noexcept -#else -# define optional_noexcept /*noexcept*/ -#endif - -#if optional_HAVE( NULLPTR ) -# define optional_nullptr nullptr -#else -# define optional_nullptr NULL -#endif - -#if optional_HAVE( REF_QUALIFIER ) -// NOLINTNEXTLINE( bugprone-macro-parentheses ) -# define optional_ref_qual & -# define optional_refref_qual && -#else -# define optional_ref_qual /*&*/ -# define optional_refref_qual /*&&*/ -#endif - -#if optional_HAVE( STATIC_ASSERT ) -# define optional_static_assert(expr, text) static_assert(expr, text); -#else -# define optional_static_assert(expr, text) /*static_assert(expr, text);*/ -#endif - -// additional includes: - -#if optional_CONFIG_NO_EXCEPTIONS -// already included: -#else -# include -#endif - -#if optional_CPP11_OR_GREATER -# include -#endif - -#if optional_HAVE( INITIALIZER_LIST ) -# include -#endif - -#if optional_HAVE( TYPE_TRAITS ) -# include -#elif optional_HAVE( TR1_TYPE_TRAITS ) -# include -#endif - -// Method enabling - -#if optional_CPP11_OR_GREATER - -#define optional_REQUIRES_0(...) \ - template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > - -#define optional_REQUIRES_T(...) \ - , typename std::enable_if< (__VA_ARGS__), int >::type = 0 - -#define optional_REQUIRES_R(R, ...) \ - typename std::enable_if< (__VA_ARGS__), R>::type - -#define optional_REQUIRES_A(...) \ - , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr - -#endif - -// -// optional: -// - -namespace nonstd { namespace optional_lite { - -namespace std11 { - -template< class T, T v > struct integral_constant { enum { value = v }; }; -template< bool B > struct bool_constant : integral_constant{}; - -typedef bool_constant< true > true_type; -typedef bool_constant< false > false_type; - -#if optional_CPP11_OR_GREATER - using std::move; -#else - template< typename T > T & move( T & t ) { return t; } -#endif - -#if optional_HAVE( CONDITIONAL ) - using std::conditional; -#else - template< bool B, typename T, typename F > struct conditional { typedef T type; }; - template< typename T, typename F > struct conditional { typedef F type; }; -#endif // optional_HAVE_CONDITIONAL - -#if optional_HAVE( IS_ASSIGNABLE ) - using std::is_assignable; -#else - template< class T, class U > struct is_assignable : std11::true_type{}; -#endif - -#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE ) - using std::is_move_constructible; -#else - template< class T > struct is_move_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE ) - using std::is_nothrow_move_assignable; -#else - template< class T > struct is_nothrow_move_assignable : std11::true_type{}; -#endif - -#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE ) - using std::is_nothrow_move_constructible; -#else - template< class T > struct is_nothrow_move_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE ) - using std::is_trivially_copy_constructible; -#else - template< class T > struct is_trivially_copy_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE ) - using std::is_trivially_move_constructible; -#else - template< class T > struct is_trivially_move_constructible : std11::true_type{}; -#endif - -} // namespace std11 - -#if optional_CPP11_OR_GREATER - -/// type traits C++17: - -namespace std17 { - -#if optional_CPP17_OR_GREATER - -using std::is_swappable; -using std::is_nothrow_swappable; - -#elif optional_CPP11_OR_GREATER - -namespace detail { - -using std::swap; - -struct is_swappable -{ - template< typename T, typename = decltype( swap( std::declval(), std::declval() ) ) > - static std11::true_type test( int /*unused*/ ); - - template< typename > - static std11::false_type test(...); -}; - -struct is_nothrow_swappable -{ - // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015): - - template< typename T > - static constexpr bool satisfies() - { - return noexcept( swap( std::declval(), std::declval() ) ); - } - - template< typename T > - static auto test( int /*unused*/ ) -> std11::integral_constant()>{} - - template< typename > - static auto test(...) -> std11::false_type; -}; - -} // namespace detail - -// is [nothow] swappable: - -template< typename T > -struct is_swappable : decltype( detail::is_swappable::test(0) ){}; - -template< typename T > -struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test(0) ){}; - -#endif // optional_CPP17_OR_GREATER - -} // namespace std17 - -/// type traits C++20: - -namespace std20 { - -template< typename T > -struct remove_cvref -{ - typedef typename std::remove_cv< typename std::remove_reference::type >::type type; -}; - -} // namespace std20 - -#endif // optional_CPP11_OR_GREATER - -/// class optional - -template< typename T > -class optional; - -namespace detail { - -// C++11 emulation: - -struct nulltype{}; - -template< typename Head, typename Tail > -struct typelist -{ - typedef Head head; - typedef Tail tail; -}; - -#if optional_CONFIG_MAX_ALIGN_HACK - -// Max align, use most restricted type for alignment: - -#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) -#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) -#define optional_UNIQUE3( name, line ) name ## line - -#define optional_ALIGN_TYPE( type ) \ - type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) - -template< typename T > -struct struct_t { T _; }; - -union max_align_t -{ - optional_ALIGN_TYPE( char ); - optional_ALIGN_TYPE( short int ); - optional_ALIGN_TYPE( int ); - optional_ALIGN_TYPE( long int ); - optional_ALIGN_TYPE( float ); - optional_ALIGN_TYPE( double ); - optional_ALIGN_TYPE( long double ); - optional_ALIGN_TYPE( char * ); - optional_ALIGN_TYPE( short int * ); - optional_ALIGN_TYPE( int * ); - optional_ALIGN_TYPE( long int * ); - optional_ALIGN_TYPE( float * ); - optional_ALIGN_TYPE( double * ); - optional_ALIGN_TYPE( long double * ); - optional_ALIGN_TYPE( void * ); - -#ifdef HAVE_LONG_LONG - optional_ALIGN_TYPE( long long ); -#endif - - struct Unknown; - - Unknown ( * optional_UNIQUE(_) )( Unknown ); - Unknown * Unknown::* optional_UNIQUE(_); - Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); - - struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_); - struct_t< Unknown * Unknown::* > optional_UNIQUE(_); - struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); -}; - -#undef optional_UNIQUE -#undef optional_UNIQUE2 -#undef optional_UNIQUE3 - -#undef optional_ALIGN_TYPE - -#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK - -// Use user-specified type for alignment: - -#define optional_ALIGN_AS( unused ) \ - optional_CONFIG_ALIGN_AS - -#else // optional_CONFIG_MAX_ALIGN_HACK - -// Determine POD type to use for alignment: - -#define optional_ALIGN_AS( to_align ) \ - typename type_of_size< alignment_types, alignment_of< to_align >::value >::type - -template< typename T > -struct alignment_of; - -template< typename T > -struct alignment_of_hack -{ - char c; - T t; - alignment_of_hack(); -}; - -template< size_t A, size_t S > -struct alignment_logic -{ - enum { value = A < S ? A : S }; -}; - -template< typename T > -struct alignment_of -{ - enum { value = alignment_logic< - sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value }; -}; - -template< typename List, size_t N > -struct type_of_size -{ - typedef typename std11::conditional< - N == sizeof( typename List::head ), - typename List::head, - typename type_of_size::type >::type type; -}; - -template< size_t N > -struct type_of_size< nulltype, N > -{ - typedef optional_CONFIG_ALIGN_AS_FALLBACK type; -}; - -template< typename T> -struct struct_t { T _; }; - -#define optional_ALIGN_TYPE( type ) \ - typelist< type , typelist< struct_t< type > - -struct Unknown; - -typedef - optional_ALIGN_TYPE( char ), - optional_ALIGN_TYPE( short ), - optional_ALIGN_TYPE( int ), - optional_ALIGN_TYPE( long ), - optional_ALIGN_TYPE( float ), - optional_ALIGN_TYPE( double ), - optional_ALIGN_TYPE( long double ), - - optional_ALIGN_TYPE( char *), - optional_ALIGN_TYPE( short * ), - optional_ALIGN_TYPE( int * ), - optional_ALIGN_TYPE( long * ), - optional_ALIGN_TYPE( float * ), - optional_ALIGN_TYPE( double * ), - optional_ALIGN_TYPE( long double * ), - - optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), - optional_ALIGN_TYPE( Unknown * Unknown::* ), - optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), - - nulltype - > > > > > > > > > > > > > > - > > > > > > > > > > > > > > - > > > > > > - alignment_types; - -#undef optional_ALIGN_TYPE - -#endif // optional_CONFIG_MAX_ALIGN_HACK - -/// C++03 constructed union to hold value. - -template< typename T > -union storage_t -{ -//private: -// template< typename > friend class optional; - - typedef T value_type; - - storage_t() optional_is_default - - explicit storage_t( value_type const & v ) - { - construct_value( v ); - } - - void construct_value( value_type const & v ) - { - ::new( value_ptr() ) value_type( v ); - } - -#if optional_CPP11_OR_GREATER - - explicit storage_t( value_type && v ) - { - construct_value( std::move( v ) ); - } - - void construct_value( value_type && v ) - { - ::new( value_ptr() ) value_type( std::move( v ) ); - } - - template< class... Args > - storage_t( nonstd_lite_in_place_t(T), Args&&... args ) - { - emplace( std::forward(args)... ); - } - - template< class... Args > - void emplace( Args&&... args ) - { - ::new( value_ptr() ) value_type( std::forward(args)... ); - } - - template< class U, class... Args > - void emplace( std::initializer_list il, Args&&... args ) - { - ::new( value_ptr() ) value_type( il, std::forward(args)... ); - } - -#endif - - void destruct_value() - { - value_ptr()->~T(); - } - - optional_nodiscard value_type const * value_ptr() const - { - return as(); - } - - value_type * value_ptr() - { - return as(); - } - - optional_nodiscard value_type const & value() const optional_ref_qual - { - return * value_ptr(); - } - - value_type & value() optional_ref_qual - { - return * value_ptr(); - } - -#if optional_HAVE( REF_QUALIFIER ) - - optional_nodiscard value_type const && value() const optional_refref_qual - { - return std::move( value() ); - } - - value_type && value() optional_refref_qual - { - return std::move( value() ); - } - -#endif - -#if optional_CPP11_OR_GREATER - - using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; - aligned_storage_t data; - -#elif optional_CONFIG_MAX_ALIGN_HACK - - typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; - - max_align_t hack; - aligned_storage_t data; - -#else - typedef optional_ALIGN_AS(value_type) align_as_type; - - typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; - aligned_storage_t data; - -# undef optional_ALIGN_AS - -#endif // optional_CONFIG_MAX_ALIGN_HACK - - optional_nodiscard void * ptr() optional_noexcept - { - return &data; - } - - optional_nodiscard void const * ptr() const optional_noexcept - { - return &data; - } - - template - optional_nodiscard U * as() - { - return reinterpret_cast( ptr() ); - } - - template - optional_nodiscard U const * as() const - { - return reinterpret_cast( ptr() ); - } -}; - -} // namespace detail - -/// disengaged state tag - -struct nullopt_t -{ - struct init{}; - explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {} -}; - -#if optional_HAVE( CONSTEXPR_11 ) -constexpr nullopt_t nullopt{ nullopt_t::init{} }; -#else -// extra parenthesis to prevent the most vexing parse: -const nullopt_t nullopt(( nullopt_t::init() )); -#endif - -/// optional access error - -#if ! optional_CONFIG_NO_EXCEPTIONS - -class bad_optional_access : public std::logic_error -{ -public: - explicit bad_optional_access() - : logic_error( "bad optional access" ) {} -}; - -#endif //optional_CONFIG_NO_EXCEPTIONS - -/// optional - -template< typename T> -class optional -{ - optional_static_assert(( !std::is_same::type, nullopt_t>::value ), - "T in optional must not be of type 'nullopt_t'.") - - optional_static_assert(( !std::is_same::type, in_place_t>::value ), - "T in optional must not be of type 'in_place_t'.") - - optional_static_assert(( std::is_object::value && std::is_destructible::value && !std::is_array::value ), - "T in optional must meet the Cpp17Destructible requirements.") - -private: - template< typename > friend class optional; - - typedef void (optional::*safe_bool)() const; - -public: - typedef T value_type; - - // x.x.3.1, constructors - - // 1a - default construct - optional_constexpr optional() optional_noexcept - : has_value_( false ) - , contained() - {} - - // 1b - construct explicitly empty - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept - : has_value_( false ) - , contained() - {} - - // 2 - copy-construct -#if optional_CPP11_OR_GREATER - // template< typename U = T - // optional_REQUIRES_T( - // std::is_copy_constructible::value - // || std11::is_trivially_copy_constructible::value - // ) - // > -#endif - optional_constexpr14 optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( other.contained.value() ); - } - } - -#if optional_CPP11_OR_GREATER - - // 3 (C++11) - move-construct from optional - template< typename U = T - optional_REQUIRES_T( - std11::is_move_constructible::value - || std11::is_trivially_move_constructible::value - ) - > - optional_constexpr14 optional( optional && other ) - // NOLINTNEXTLINE( performance-noexcept-move-constructor ) - noexcept( std11::is_nothrow_move_constructible::value ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( std::move( other.contained.value() ) ); - } - } - - // 4a (C++11) - explicit converting copy-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std::is_convertible< U const & , T>::value /*=> explicit */ - ) - > - explicit optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( T{ other.contained.value() } ); - } - } -#endif // optional_CPP11_OR_GREATER - - // 4b (C++98 and later) - non-explicit converting copy-construct from optional - template< typename U -#if optional_CPP11_OR_GREATER - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && std::is_convertible< U const & , T>::value /*=> non-explicit */ - ) -#endif // optional_CPP11_OR_GREATER - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - /*non-explicit*/ optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( other.contained.value() ); - } - } - -#if optional_CPP11_OR_GREATER - - // 5a (C++11) - explicit converting move-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std::is_convertible< U &&, T>::value /*=> explicit */ - ) - > - explicit optional( optional && other - ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( T{ std::move( other.contained.value() ) } ); - } - } - - // 5a (C++11) - non-explicit converting move-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && std::is_convertible< U &&, T>::value /*=> non-explicit */ - ) - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - /*non-explicit*/ optional( optional && other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( std::move( other.contained.value() ) ); - } - } - - // 6 (C++11) - in-place construct - template< typename... Args - optional_REQUIRES_T( - std::is_constructible::value - ) - > - optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args ) - : has_value_( true ) - , contained( in_place, std::forward(args)... ) - {} - - // 7 (C++11) - in-place construct, initializer-list - template< typename U, typename... Args - optional_REQUIRES_T( - std::is_constructible&, Args&&...>::value - ) - > - optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list il, Args&&... args ) - : has_value_( true ) - , contained( T( il, std::forward(args)...) ) - {} - - // 8a (C++11) - explicit move construct from value - template< typename U = T - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && !std::is_convertible::value /*=> explicit */ - ) - > - optional_constexpr explicit optional( U && value ) - : has_value_( true ) - , contained( nonstd_lite_in_place(T), std::forward( value ) ) - {} - - // 8b (C++11) - non-explicit move construct from value - template< typename U = T - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && std::is_convertible::value /*=> non-explicit */ - ) - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional_constexpr /*non-explicit*/ optional( U && value ) - : has_value_( true ) - , contained( nonstd_lite_in_place(T), std::forward( value ) ) - {} - -#else // optional_CPP11_OR_GREATER - - // 8 (C++98) - optional( value_type const & value ) - : has_value_( true ) - , contained( value ) - {} - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.2, destructor - - ~optional() - { - if ( has_value() ) - { - contained.destruct_value(); - } - } - - // x.x.3.3, assignment - - // 1 (C++98and later) - assign explicitly empty - optional & operator=( nullopt_t /*unused*/) optional_noexcept - { - reset(); - return *this; - } - - // 2 (C++98and later) - copy-assign from optional -#if optional_CPP11_OR_GREATER - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - true -// std::is_copy_constructible::value -// && std::is_copy_assignable::value - ) - operator=( optional const & other ) - noexcept( - std11::is_nothrow_move_assignable::value - && std11::is_nothrow_move_constructible::value - ) -#else - optional & operator=( optional const & other ) -#endif - { - if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); } - else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; } - return *this; - } - -#if optional_CPP11_OR_GREATER - - // 3 (C++11) - move-assign from optional - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - true -// std11::is_move_constructible::value -// && std::is_move_assignable::value - ) - operator=( optional && other ) noexcept - { - if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); } - else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); } - return *this; - } - - // 4 (C++11) - move-assign from value - template< typename U = T > - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - std::is_constructible::value - && std11::is_assignable::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && !(std::is_scalar::value && std::is_same::type>::value) - ) - operator=( U && value ) - { - if ( has_value() ) - { - contained.value() = std::forward( value ); - } - else - { - initialize( T( std::forward( value ) ) ); - } - return *this; - } - -#else // optional_CPP11_OR_GREATER - - // 4 (C++98) - copy-assign from value - template< typename U /*= T*/ > - optional & operator=( U const & value ) - { - if ( has_value() ) contained.value() = value; - else initialize( T( value ) ); - return *this; - } - -#endif // optional_CPP11_OR_GREATER - - // 5 (C++98 and later) - converting copy-assign from optional - template< typename U > -#if optional_CPP11_OR_GREATER - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional&, - std::is_constructible< T , U const &>::value - && std11::is_assignable< T&, U const &>::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std11::is_assignable< T&, optional & >::value - && !std11::is_assignable< T&, optional && >::value - && !std11::is_assignable< T&, optional const & >::value - && !std11::is_assignable< T&, optional const && >::value - ) -#else - optional& -#endif // optional_CPP11_OR_GREATER - operator=( optional const & other ) - { - return *this = optional( other ); - } - -#if optional_CPP11_OR_GREATER - - // 6 (C++11) - converting move-assign from optional - template< typename U > - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional&, - std::is_constructible< T , U>::value - && std11::is_assignable< T&, U>::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std11::is_assignable< T&, optional & >::value - && !std11::is_assignable< T&, optional && >::value - && !std11::is_assignable< T&, optional const & >::value - && !std11::is_assignable< T&, optional const && >::value - ) - operator=( optional && other ) - { - return *this = optional( std::move( other ) ); - } - - // 7 (C++11) - emplace - template< typename... Args - optional_REQUIRES_T( - std::is_constructible::value - ) - > - T& emplace( Args&&... args ) - { - *this = nullopt; - contained.emplace( std::forward(args)... ); - has_value_ = true; - return contained.value(); - } - - // 8 (C++11) - emplace, initializer-list - template< typename U, typename... Args - optional_REQUIRES_T( - std::is_constructible&, Args&&...>::value - ) - > - T& emplace( std::initializer_list il, Args&&... args ) - { - *this = nullopt; - contained.emplace( il, std::forward(args)... ); - has_value_ = true; - return contained.value(); - } - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.4, swap - - void swap( optional & other ) -#if optional_CPP11_OR_GREATER - noexcept( - std11::is_nothrow_move_constructible::value - && std17::is_nothrow_swappable::value - ) -#endif - { - using std::swap; - if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); } - else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); } - } - - // x.x.3.5, observers - - optional_constexpr value_type const * operator ->() const - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr14 value_type * operator ->() - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr value_type const & operator *() const optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - - optional_constexpr14 value_type & operator *() optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - -#if optional_HAVE( REF_QUALIFIER ) - - optional_constexpr value_type const && operator *() const optional_refref_qual - { - return std::move( **this ); - } - - optional_constexpr14 value_type && operator *() optional_refref_qual - { - return std::move( **this ); - } - -#endif - -#if optional_CPP11_OR_GREATER - optional_constexpr explicit operator bool() const optional_noexcept - { - return has_value(); - } -#else - optional_constexpr operator safe_bool() const optional_noexcept - { - return has_value() ? &optional::this_type_does_not_support_comparisons : 0; - } -#endif - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept - { - return has_value_; - } - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual - { -#if optional_CONFIG_NO_EXCEPTIONS - assert( has_value() ); -#else - if ( ! has_value() ) - { - throw bad_optional_access(); - } -#endif - return contained.value(); - } - - optional_constexpr14 value_type & value() optional_ref_qual - { -#if optional_CONFIG_NO_EXCEPTIONS - assert( has_value() ); -#else - if ( ! has_value() ) - { - throw bad_optional_access(); - } -#endif - return contained.value(); - } - -#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 ) - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual - { - return std::move( value() ); - } - - optional_constexpr14 value_type && value() optional_refref_qual - { - return std::move( value() ); - } - -#endif - -#if optional_HAVE( REF_QUALIFIER ) - - template< typename U > - optional_constexpr value_type value_or( U && v ) const optional_ref_qual - { - return has_value() ? contained.value() : static_cast(std::forward( v ) ); - } - - template< typename U > - optional_constexpr14 value_type value_or( U && v ) optional_refref_qual - { -#if optional_COMPILER_CLANG_VERSION - return has_value() ? /*std::move*/( contained.value() ) : static_cast(std::forward( v ) ); -#else - return has_value() ? std::move( contained.value() ) : static_cast(std::forward( v ) ); -#endif - } - -#else - - template< typename U > - optional_constexpr value_type value_or( U const & v ) const - { - return has_value() ? contained.value() : static_cast( v ); - } - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.6, modifiers - - void reset() optional_noexcept - { - if ( has_value() ) - { - contained.destruct_value(); - } - - has_value_ = false; - } - -private: - void this_type_does_not_support_comparisons() const {} - - template< typename V > - void initialize( V const & value ) - { - assert( ! has_value() ); - contained.construct_value( value ); - has_value_ = true; - } - -#if optional_CPP11_OR_GREATER - template< typename V > - void initialize( V && value ) - { - assert( ! has_value() ); - contained.construct_value( std::move( value ) ); - has_value_ = true; - } - -#endif - -private: - bool has_value_; - detail::storage_t< value_type > contained; - -}; - -// Relational operators - -template< typename T, typename U > -inline optional_constexpr bool operator==( optional const & x, optional const & y ) -{ - return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( optional const & x, optional const & y ) -{ - return !(x == y); -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( optional const & x, optional const & y ) -{ - return (!y) ? false : (!x) ? true : *x < *y; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( optional const & x, optional const & y ) -{ - return (y < x); -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( optional const & x, optional const & y ) -{ - return !(y < x); -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( optional const & x, optional const & y ) -{ - return !(x < y); -} - -// Comparison with nullopt - -template< typename T > -inline optional_constexpr bool operator==( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator!=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator<( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept -{ - return false; -} - -template< typename T > -inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator<=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept -{ - return true; -} - -template< typename T > -inline optional_constexpr bool operator>( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept -{ - return false; -} - -template< typename T > -inline optional_constexpr bool operator>=( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept -{ - return true; -} - -template< typename T > -inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return (!x); -} - -// Comparison with T - -template< typename T, typename U > -inline optional_constexpr bool operator==( optional const & x, U const & v ) -{ - return bool(x) ? *x == v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator==( U const & v, optional const & x ) -{ - return bool(x) ? v == *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( optional const & x, U const & v ) -{ - return bool(x) ? *x != v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( U const & v, optional const & x ) -{ - return bool(x) ? v != *x : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( optional const & x, U const & v ) -{ - return bool(x) ? *x < v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( U const & v, optional const & x ) -{ - return bool(x) ? v < *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( optional const & x, U const & v ) -{ - return bool(x) ? *x <= v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( U const & v, optional const & x ) -{ - return bool(x) ? v <= *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( optional const & x, U const & v ) -{ - return bool(x) ? *x > v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( U const & v, optional const & x ) -{ - return bool(x) ? v > *x : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( optional const & x, U const & v ) -{ - return bool(x) ? *x >= v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( U const & v, optional const & x ) -{ - return bool(x) ? v >= *x : true; -} - -// Specialized algorithms - -template< typename T -#if optional_CPP11_OR_GREATER - optional_REQUIRES_T( - std11::is_move_constructible::value - && std17::is_swappable::value ) -#endif -> -void swap( optional & x, optional & y ) -#if optional_CPP11_OR_GREATER - noexcept( noexcept( x.swap(y) ) ) -#endif -{ - x.swap( y ); -} - -#if optional_CPP11_OR_GREATER - -template< typename T > -optional_constexpr optional< typename std::decay::type > make_optional( T && value ) -{ - return optional< typename std::decay::type >( std::forward( value ) ); -} - -template< typename T, typename...Args > -optional_constexpr optional make_optional( Args&&... args ) -{ - return optional( nonstd_lite_in_place(T), std::forward(args)...); -} - -template< typename T, typename U, typename... Args > -optional_constexpr optional make_optional( std::initializer_list il, Args&&... args ) -{ - return optional( nonstd_lite_in_place(T), il, std::forward(args)...); -} - -#else - -template< typename T > -optional make_optional( T const & value ) -{ - return optional( value ); -} - -#endif // optional_CPP11_OR_GREATER - -} // namespace optional_lite - -using optional_lite::optional; -using optional_lite::nullopt_t; -using optional_lite::nullopt; - -#if ! optional_CONFIG_NO_EXCEPTIONS -using optional_lite::bad_optional_access; -#endif - -using optional_lite::make_optional; - -} // namespace nonstd - -#if optional_CPP11_OR_GREATER - -// specialize the std::hash algorithm: - -namespace std { - -template< class T > -struct hash< nonstd::optional > -{ -public: - std::size_t operator()( nonstd::optional const & v ) const optional_noexcept - { - return bool( v ) ? std::hash{}( *v ) : 0; - } -}; - -} //namespace std - -#endif // optional_CPP11_OR_GREATER - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER ) -# pragma warning( pop ) -#endif - -#endif // optional_USES_STD_OPTIONAL - -#endif // NONSTD_OPTIONAL_LITE_HPP diff --git a/src/util/Tokenizer.hpp b/src/util/Tokenizer.hpp index d139832e6..763185b77 100644 --- a/src/util/Tokenizer.hpp +++ b/src/util/Tokenizer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -21,7 +21,6 @@ #include #include -#include #include namespace util { diff --git a/src/util/string.cpp b/src/util/string.cpp index aa0ff368e..6c390f355 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -48,8 +48,8 @@ parse_double(const std::string& value) nonstd::expected parse_signed(const std::string& value, - const nonstd::optional min_value, - const nonstd::optional max_value, + const std::optional min_value, + const std::optional max_value, const nonstd::string_view description) { const std::string stripped_value = strip_whitespace(value); @@ -86,8 +86,8 @@ parse_umask(const std::string& value) nonstd::expected parse_unsigned(const std::string& value, - const nonstd::optional min_value, - const nonstd::optional max_value, + const std::optional min_value, + const std::optional max_value, const nonstd::string_view description, const int base) { @@ -197,12 +197,12 @@ replace_first(const nonstd::string_view string, return result; } -std::pair> +std::pair> split_once(const nonstd::string_view string, const char split_char) { const size_t sep_pos = string.find(split_char); if (sep_pos == nonstd::string_view::npos) { - return std::make_pair(string, nonstd::nullopt); + return std::make_pair(string, std::nullopt); } else { return std::make_pair(string.substr(0, sep_pos), string.substr(sep_pos + 1)); diff --git a/src/util/string.hpp b/src/util/string.hpp index 19f211904..adc77bf85 100644 --- a/src/util/string.hpp +++ b/src/util/string.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -19,12 +19,12 @@ #pragma once #include -#include #include #include // for mode_t #include +#include #include #include @@ -60,8 +60,8 @@ nonstd::expected parse_double(const std::string& value); // included in the error message for range violations. nonstd::expected parse_signed(const std::string& value, - nonstd::optional min_value = nonstd::nullopt, - nonstd::optional max_value = nonstd::nullopt, + std::optional min_value = std::nullopt, + std::optional max_value = std::nullopt, nonstd::string_view description = "integer"); // Parse `value` (an octal integer). @@ -75,8 +75,8 @@ nonstd::expected parse_umask(const std::string& value); // `description` is included in the error message for range violations. nonstd::expected parse_unsigned(const std::string& value, - nonstd::optional min_value = nonstd::nullopt, - nonstd::optional max_value = nonstd::nullopt, + std::optional min_value = std::nullopt, + std::optional max_value = std::nullopt, nonstd::string_view description = "integer", int base = 10); @@ -98,7 +98,7 @@ std::string replace_first(nonstd::string_view string, // Split `string` into two parts using `split_char` as the delimiter. The second // part will be `nullopt` if there is no `split_char` in `string.` -std::pair> +std::pair> split_once(nonstd::string_view string, char split_char); // Return true if `prefix` is a prefix of `string`. diff --git a/unittest/test_Args.cpp b/unittest/test_Args.cpp index db656079c..81a609de2 100644 --- a/unittest/test_Args.cpp +++ b/unittest/test_Args.cpp @@ -84,7 +84,7 @@ TEST_CASE("Args::from_atfile") SUBCASE("Nonexistent file") { - CHECK(Args::from_atfile("at_file") == nonstd::nullopt); + CHECK(Args::from_atfile("at_file") == std::nullopt); } SUBCASE("Empty") diff --git a/unittest/test_Config.cpp b/unittest/test_Config.cpp index 07443ecba..329464418 100644 --- a/unittest/test_Config.cpp +++ b/unittest/test_Config.cpp @@ -75,7 +75,7 @@ TEST_CASE("Config: default values") CHECK(config.sloppiness().to_bitmask() == 0); CHECK(config.stats()); CHECK(config.temporary_dir().empty()); // Set later - CHECK(config.umask() == nonstd::nullopt); + CHECK(config.umask() == std::nullopt); } TEST_CASE("Config::update_from_file") @@ -227,7 +227,7 @@ TEST_CASE("Config::update_from_file, error handling") { Util::write_file("ccache.conf", "umask = "); CHECK(config.update_from_file("ccache.conf")); - CHECK(config.umask() == nonstd::nullopt); + CHECK(config.umask() == std::nullopt); } SUBCASE("invalid size") diff --git a/unittest/test_Util.cpp b/unittest/test_Util.cpp index 72c617966..552f5c36b 100644 --- a/unittest/test_Util.cpp +++ b/unittest/test_Util.cpp @@ -26,10 +26,11 @@ #include #include "third_party/doctest.h" -#include "third_party/nonstd/optional.hpp" #include +#include + #ifdef HAVE_UNISTD_H # include #endif @@ -37,7 +38,6 @@ #include using doctest::Approx; -using nonstd::nullopt; using TestUtil::TestContext; TEST_SUITE_BEGIN("Util"); diff --git a/unittest/test_ccache.cpp b/unittest/test_ccache.cpp index 88125e233..9c1628835 100644 --- a/unittest/test_ccache.cpp +++ b/unittest/test_ccache.cpp @@ -24,7 +24,8 @@ #include #include "third_party/doctest.h" -#include "third_party/nonstd/optional.hpp" + +#include #ifdef HAVE_UNISTD_H # include diff --git a/unittest/test_util_string.cpp b/unittest/test_util_string.cpp index f914f3d4c..70d831ef5 100644 --- a/unittest/test_util_string.cpp +++ b/unittest/test_util_string.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -24,8 +24,8 @@ static bool operator==( - std::pair> left, - std::pair> right) + std::pair> left, + std::pair> right) { return left.first == right.first && left.second == right.second; } @@ -100,9 +100,9 @@ TEST_CASE("util::parse_signed") CHECK(util::parse_signed("0x4").error() == "invalid integer: \"0x4\""); // Custom description not used for invalid value. - CHECK(util::parse_signed("apple", nonstd::nullopt, nonstd::nullopt, "banana") - .error() - == "invalid integer: \"apple\""); + CHECK( + util::parse_signed("apple", std::nullopt, std::nullopt, "banana").error() + == "invalid integer: \"apple\""); // Boundary values. CHECK(util::parse_signed("-9223372036854775809").error() @@ -158,8 +158,7 @@ TEST_CASE("util::parse_unsigned") // Custom description not used for invalid value. CHECK( - util::parse_unsigned("apple", nonstd::nullopt, nonstd::nullopt, "banana") - .error() + util::parse_unsigned("apple", std::nullopt, std::nullopt, "banana").error() == "invalid unsigned integer: \"apple\""); // Boundary values. @@ -171,11 +170,11 @@ TEST_CASE("util::parse_unsigned") == "invalid unsigned integer: \"18446744073709551616\""); // Base - CHECK(*util::parse_unsigned("0666", nonstd::nullopt, nonstd::nullopt, "", 8) + CHECK(*util::parse_unsigned("0666", std::nullopt, std::nullopt, "", 8) == 0666); - CHECK(*util::parse_unsigned("0666", nonstd::nullopt, nonstd::nullopt, "", 10) + CHECK(*util::parse_unsigned("0666", std::nullopt, std::nullopt, "", 10) == 666); - CHECK(*util::parse_unsigned("0666", nonstd::nullopt, nonstd::nullopt, "", 16) + CHECK(*util::parse_unsigned("0666", std::nullopt, std::nullopt, "", 16) == 0x666); } @@ -227,8 +226,8 @@ TEST_CASE("util::replace_first") TEST_CASE("util::split_once") { - using nonstd::nullopt; using std::make_pair; + using std::nullopt; using util::split_once; CHECK(split_once("", '=') == make_pair("", nullopt)); -- 2.47.2