diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2017-03-28 15:05:55 -0700 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2017-03-28 18:59:57 -0700 |
| commit | 42bd55e3ae815e43181facfdc161d29804014f26 (patch) | |
| tree | d0e4db89947aa557ec6e3bf6065cfb43cbc796ff | |
| parent | 67ce764c2ea7483860a3ad61441608d8978605ae (diff) | |
| download | vcpkg-42bd55e3ae815e43181facfdc161d29804014f26.tar.gz vcpkg-42bd55e3ae815e43181facfdc161d29804014f26.zip | |
Rework optional<T>
| -rw-r--r-- | toolsrc/include/vcpkg_optional.h | 79 | ||||
| -rw-r--r-- | toolsrc/src/commands_ci.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/commands_edit.cpp | 12 | ||||
| -rw-r--r-- | toolsrc/src/commands_install.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/commands_integrate.cpp | 3 | ||||
| -rw-r--r-- | toolsrc/src/metrics.cpp | 6 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Dependencies.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Environment.cpp | 69 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_System.cpp | 19 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_paths.cpp | 19 |
11 files changed, 154 insertions, 85 deletions
diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h index 7b935bea9..745377a82 100644 --- a/toolsrc/include/vcpkg_optional.h +++ b/toolsrc/include/vcpkg_optional.h @@ -1,5 +1,78 @@ #pragma once -#include <memory> +#include "LineInfo.h" +#include "vcpkg_Checks.h" -template<class T> -using optional = std::unique_ptr<T>; +namespace vcpkg +{ + struct nullopt_t + { + explicit constexpr nullopt_t(int) {} + }; + + const static constexpr nullopt_t nullopt{ 0 }; + + template <class T> + class optional + { + public: + // Constructors are intentionally implicit + constexpr optional(nullopt_t) : m_is_present(false), m_t() { } + + optional(const T& t) : m_is_present(true), m_t(t) { } + + optional(T&& t) : m_is_present(true), m_t(std::move(t)) { } + + T&& get_or_exit(const LineInfo& line_info) && + { + this->exit_if_null(line_info); + return std::move(this->m_t); + } + + const T& get_or_exit(const LineInfo& line_info) const & + { + this->exit_if_null(line_info); + return this->m_t; + } + + constexpr explicit operator bool() const + { + return this->m_is_present; + } + + constexpr bool has_value() const + { + return m_is_present; + } + + template <class U> + T value_or(U&& default_value) const & + { + return bool(*this) ? this->m_t : static_cast<T>(std::forward<U>(default_value)); + } + + template <class U> + T value_or(U&& default_value) && + { + return bool(*this) ? std::move(this->m_t) : static_cast<T>(std::forward<U>(default_value)); + } + + const T* get() const + { + return bool(*this) ? &this->m_t : nullptr; + } + + T* get() + { + return bool(*this) ? &this->m_t : nullptr; + } + + private: + void exit_if_null(const LineInfo& line_info) const + { + Checks::check_exit(line_info, this->m_is_present, "Value was null"); + } + + bool m_is_present; + T m_t; + }; +} diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index bfe87b35f..2d7016bcc 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -62,7 +62,11 @@ namespace vcpkg::Commands::CI } else if (action.plan.plan_type == install_plan_type::BUILD_AND_INSTALL) { - const BuildResult result = Commands::Build::build_package(*action.plan.source_pgh, action.spec, paths, paths.port_dir(action.spec), status_db); + const BuildResult result = Commands::Build::build_package(action.plan.source_pgh.get_or_exit(VCPKG_LINE_INFO), + action.spec, + paths, + paths.port_dir(action.spec), + status_db); timing.back() = build_timer.elapsed<std::chrono::milliseconds>().count(); results.back() = result; if (result != BuildResult::SUCCEEDED) @@ -77,7 +81,7 @@ namespace vcpkg::Commands::CI else if (action.plan.plan_type == install_plan_type::INSTALL) { results.back() = BuildResult::SUCCEEDED; - Install::install_package(paths, *action.plan.binary_pgh, &status_db); + Install::install_package(paths, action.plan.binary_pgh.get_or_exit(VCPKG_LINE_INFO), &status_db); System::println(System::color::success, "Package %s is installed from cache", action.spec); } else diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp index d9cd627d2..4faf10bb9 100644 --- a/toolsrc/src/commands_edit.cpp +++ b/toolsrc/src/commands_edit.cpp @@ -22,9 +22,9 @@ namespace vcpkg::Commands::Edit if (env_EDITOR.empty()) { const optional<std::wstring> env_EDITOR_optional = System::get_environmental_variable(L"EDITOR"); - if (env_EDITOR_optional) + if (auto e = env_EDITOR_optional.get()) { - env_EDITOR = *env_EDITOR_optional; + env_EDITOR = *e; } } @@ -47,16 +47,16 @@ namespace vcpkg::Commands::Edit }; for (auto&& keypath : regkeys) { - auto code_installpath = System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); - if (code_installpath) + const optional<std::wstring> code_installpath = System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); + if (auto c = code_installpath.get()) { - auto p = fs::path(*code_installpath) / "Code.exe"; + auto p = fs::path(*c) / "Code.exe"; if (fs::exists(p)) { env_EDITOR = p.native(); break; } - auto p_insiders = fs::path(*code_installpath) / "Code - Insiders.exe"; + auto p_insiders = fs::path(*c) / "Code - Insiders.exe"; if (fs::exists(p_insiders)) { env_EDITOR = p_insiders.native(); diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 0b2062a7e..6c8ab8be4 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -216,7 +216,11 @@ namespace vcpkg::Commands::Install } else if (action.plan.plan_type == install_plan_type::BUILD_AND_INSTALL) { - const Build::BuildResult result = Commands::Build::build_package(*action.plan.source_pgh, action.spec, paths, paths.port_dir(action.spec), status_db); + const Build::BuildResult result = Commands::Build::build_package(action.plan.source_pgh.get_or_exit(VCPKG_LINE_INFO), + action.spec, + paths, + paths.port_dir(action.spec), + status_db); if (result != Build::BuildResult::SUCCEEDED) { System::println(System::color::error, Build::create_error_message(result, action.spec)); @@ -229,7 +233,7 @@ namespace vcpkg::Commands::Install } else if (action.plan.plan_type == install_plan_type::INSTALL) { - install_package(paths, *action.plan.binary_pgh, &status_db); + install_package(paths, action.plan.binary_pgh.get_or_exit(VCPKG_LINE_INFO), &status_db); System::println(System::color::success, "Package %s is installed", action.spec); } else diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index b72a7a483..9342fc71e 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -136,7 +136,8 @@ namespace vcpkg::Commands::Integrate static fs::path get_appdata_targets_path() { - return fs::path(*System::get_environmental_variable(L"LOCALAPPDATA")) / "vcpkg" / "vcpkg.user.targets"; + static const fs::path local_app_data = fs::path(System::get_environmental_variable(L"LOCALAPPDATA").get_or_exit(VCPKG_LINE_INFO)); + return local_app_data / "vcpkg" / "vcpkg.user.targets"; } static void integrate_install(const vcpkg_paths& paths) diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp index d0e20fe2d..2fdbe8f09 100644 --- a/toolsrc/src/metrics.cpp +++ b/toolsrc/src/metrics.cpp @@ -228,11 +228,7 @@ true std::wstring GetSQMUser() { auto hkcu_sqmclient = System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); - - if (hkcu_sqmclient) - return std::move(*hkcu_sqmclient); - else - return L"{}"; + return hkcu_sqmclient.value_or(L"{}"); } void SetUserInformation(const std::string& user_id, const std::string& first_use_time) diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 48c0c7e32..069d9a7c1 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -46,9 +46,9 @@ static void inner(const vcpkg_cmd_arguments& args) else { const optional<std::wstring> vcpkg_root_dir_env = System::get_environmental_variable(L"VCPKG_ROOT"); - if (vcpkg_root_dir_env) + if (auto v = vcpkg_root_dir_env.get()) { - vcpkg_root_dir = fs::absolute(*vcpkg_root_dir_env); + vcpkg_root_dir = fs::absolute(*v); } else { @@ -77,9 +77,9 @@ static void inner(const vcpkg_cmd_arguments& args) else { const optional<std::wstring> vcpkg_default_triplet_env = System::get_environmental_variable(L"VCPKG_DEFAULT_TRIPLET"); - if (vcpkg_default_triplet_env) + if (auto v = vcpkg_default_triplet_env.get()) { - default_target_triplet = triplet::from_canonical_name(Strings::utf16_to_utf8(*vcpkg_default_triplet_env)); + default_target_triplet = triplet::from_canonical_name(Strings::utf16_to_utf8(*v)); } else { diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4233279cf..dad144cfb 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -9,7 +9,7 @@ namespace vcpkg::Dependencies { - install_plan_action::install_plan_action() : plan_type(install_plan_type::UNKNOWN), binary_pgh(nullptr), source_pgh(nullptr) + install_plan_action::install_plan_action() : plan_type(install_plan_type::UNKNOWN), binary_pgh(nullopt), source_pgh(nullopt) { } @@ -68,7 +68,7 @@ namespace vcpkg::Dependencies auto it = status_db.find(spec); if (it != status_db.end() && (*it)->want == want_t::install) { - was_examined.emplace(spec, install_plan_action{install_plan_type::ALREADY_INSTALLED, nullptr, nullptr}); + was_examined.emplace(spec, install_plan_action{install_plan_type::ALREADY_INSTALLED, nullopt, nullopt }); continue; } @@ -76,7 +76,7 @@ namespace vcpkg::Dependencies if (BinaryParagraph* bpgh = maybe_bpgh.get()) { process_dependencies(bpgh->depends); - was_examined.emplace(spec, install_plan_action{install_plan_type::INSTALL, std::make_unique<BinaryParagraph>(std::move(*bpgh)), nullptr}); + was_examined.emplace(spec, install_plan_action{install_plan_type::INSTALL, std::move(*bpgh), nullopt }); continue; } @@ -84,7 +84,7 @@ namespace vcpkg::Dependencies SourceParagraph* spgh = maybe_spgh.get(); Checks::check_exit(VCPKG_LINE_INFO, spgh != nullptr, "Cannot find package %s", spec.name()); process_dependencies(filter_dependencies(spgh->depends, spec.target_triplet())); - was_examined.emplace(spec, install_plan_action{install_plan_type::BUILD_AND_INSTALL, nullptr, std::make_unique<SourceParagraph>(std::move(*spgh))}); + was_examined.emplace(spec, install_plan_action{install_plan_type::BUILD_AND_INSTALL, nullopt, std::move(*spgh)}); } std::vector<package_spec_with_install_plan> ret; diff --git a/toolsrc/src/vcpkg_Environment.cpp b/toolsrc/src/vcpkg_Environment.cpp index ca68498ef..d28a25017 100644 --- a/toolsrc/src/vcpkg_Environment.cpp +++ b/toolsrc/src/vcpkg_Environment.cpp @@ -19,14 +19,14 @@ namespace vcpkg::Environment static optional<fs::path> find_vs2015_installation_instance() { const optional<std::wstring> vs2015_cmntools_optional = System::get_environmental_variable(L"VS140COMNTOOLS"); - if (!vs2015_cmntools_optional) + if (auto v = vs2015_cmntools_optional.get()) { - return nullptr; + static const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because the env variable has a trailing backslash + static const fs::path vs2015_path = vs2015_cmntools.parent_path().parent_path(); + return vs2015_path; } - static const fs::path vs2015_cmntools = fs::path(*vs2015_cmntools_optional).parent_path(); // The call to parent_path() is needed because the env variable has a trailing backslash - static const fs::path vs2015_path = vs2015_cmntools.parent_path().parent_path(); - return std::make_unique<fs::path>(vs2015_path); + return nullopt; } static const optional<fs::path>& get_VS2015_installation_instance() @@ -69,9 +69,9 @@ namespace vcpkg::Environment // VS2015 const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance(); - if (vs_2015_installation_instance) + if (auto v = vs_2015_installation_instance.get()) { - const fs::path vs2015_dumpbin_exe = *vs_2015_installation_instance / "VC" / "bin" / "dumpbin.exe"; + const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); if (fs::exists(vs2015_dumpbin_exe)) { @@ -112,9 +112,9 @@ namespace vcpkg::Environment // VS2015 const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance(); - if (vs_2015_installation_instance) + if (auto v = vs_2015_installation_instance.get()) { - const fs::path vs2015_vcvarsall_bat = *vs_2015_installation_instance / "VC" / "vcvarsall.bat"; + const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2015_vcvarsall_bat); if (fs::exists(vs2015_vcvarsall_bat)) @@ -138,50 +138,37 @@ namespace vcpkg::Environment return vcvarsall_bat; } - static fs::path find_ProgramFiles() - { - const optional<std::wstring> program_files = System::get_environmental_variable(L"PROGRAMFILES"); - Checks::check_exit(VCPKG_LINE_INFO, program_files.get() != nullptr, "Could not detect the PROGRAMFILES environmental variable"); - return *program_files; - } - static const fs::path& get_ProgramFiles() { - static const fs::path p = find_ProgramFiles(); + static const fs::path p = System::get_environmental_variable(L"PROGRAMFILES").get_or_exit(VCPKG_LINE_INFO); return p; } - static fs::path find_ProgramFiles_32_bit() - { - const optional<std::wstring> program_files_X86 = System::get_environmental_variable(L"ProgramFiles(x86)"); - if (program_files_X86) - { - return *program_files_X86; - } - - return get_ProgramFiles(); - } - const fs::path& get_ProgramFiles_32_bit() { - static const fs::path p = find_ProgramFiles_32_bit(); + static const fs::path p = []() -> fs::path + { + auto value = System::get_environmental_variable(L"ProgramFiles(x86)"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_ProgramFiles(); + }(); return p; } - static fs::path find_ProgramFiles_platform_bitness() - { - const optional<std::wstring> program_files_W6432 = System::get_environmental_variable(L"ProgramW6432"); - if (program_files_W6432) - { - return *program_files_W6432; - } - - return get_ProgramFiles(); - } - const fs::path& get_ProgramFiles_platform_bitness() { - static const fs::path p = find_ProgramFiles_platform_bitness(); + static const fs::path p = []() -> fs::path + { + auto value = System::get_environmental_variable(L"ProgramW6432"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_ProgramFiles(); + }(); return p; } } diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 5518e4c45..221a201ed 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -15,7 +15,7 @@ namespace vcpkg::System int cmd_execute_clean(const cwstring_view cmd_line) { - static const std::wstring system_root = *get_environmental_variable(L"SystemRoot"); + static const std::wstring system_root = get_environmental_variable(L"SystemRoot").get_or_exit(VCPKG_LINE_INFO); static const std::wstring system_32 = system_root + LR"(\system32)"; static const std::wstring new_PATH = Strings::wformat(LR"(Path=%s;%s;%s\WindowsPowerShell\v1.0\)", system_32, system_root, system_32); @@ -69,8 +69,9 @@ namespace vcpkg::System for (auto&& env_wstring : env_wstrings) { - auto v = System::get_environmental_variable(env_wstring.c_str()); - if (v == nullptr || v->empty()) + const optional<std::wstring> value = System::get_environmental_variable(env_wstring.c_str()); + auto v = value.get(); + if (!v || v->empty()) continue; env_wstring.push_back(L'='); @@ -164,14 +165,14 @@ namespace vcpkg::System { auto sz = GetEnvironmentVariableW(varname, nullptr, 0); if (sz == 0) - return nullptr; + return nullopt; auto ret = std::make_unique<std::wstring>(sz, L'\0'); Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret->size()); auto sz2 = GetEnvironmentVariableW(varname, ret->data(), static_cast<DWORD>(ret->size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret->pop_back(); - return ret; + return *ret.release(); } void set_environmental_variable(const cwstring_view varname, const cwstring_view varvalue) noexcept @@ -189,21 +190,21 @@ namespace vcpkg::System HKEY k = nullptr; LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) - return nullptr; + return nullopt; DWORD dwBufferSize = 0; DWORD dwType = 0; auto rc = RegQueryValueExW(k, valuename, nullptr, &dwType, nullptr, &dwBufferSize); if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize == 0 || dwBufferSize % sizeof(wchar_t) != 0) - return nullptr; + return nullopt; std::wstring ret; ret.resize(dwBufferSize / sizeof(wchar_t)); rc = RegQueryValueExW(k, valuename, nullptr, &dwType, reinterpret_cast<LPBYTE>(ret.data()), &dwBufferSize); if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize != sizeof(wchar_t) * ret.size()) - return nullptr; + return nullopt; ret.pop_back(); // remove extra trailing null byte - return std::make_unique<std::wstring>(std::move(ret)); + return ret; } } diff --git a/toolsrc/src/vcpkg_paths.cpp b/toolsrc/src/vcpkg_paths.cpp index 732c4a4fc..86106028a 100644 --- a/toolsrc/src/vcpkg_paths.cpp +++ b/toolsrc/src/vcpkg_paths.cpp @@ -47,10 +47,10 @@ namespace vcpkg if (it != candidate_paths.cend()) { - return std::make_unique<fs::path>(std::move(*it)); + return std::move(*it); } - return nullptr; + return nullopt; } static std::vector<fs::path> find_from_PATH(const std::wstring& name) @@ -101,9 +101,10 @@ namespace vcpkg candidate_paths.push_back(Environment::get_ProgramFiles_platform_bitness() / "CMake" / "bin" / "cmake.exe"); candidate_paths.push_back(Environment::get_ProgramFiles_32_bit() / "CMake" / "bin"); - if (auto ret = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version)) + const optional<fs::path> path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); + if (auto p = path.get()) { - return *ret; + return *p; } return fetch_dependency(scripts_folder, L"cmake", downloaded_copy); @@ -121,9 +122,10 @@ namespace vcpkg candidate_paths.push_back(downloaded_copy); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - if (auto ret = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version)) + auto path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); + if (auto p = path.get()) { - return *ret; + return *p; } return fetch_dependency(scripts_folder, L"nuget", downloaded_copy); @@ -143,9 +145,10 @@ namespace vcpkg candidate_paths.push_back(Environment::get_ProgramFiles_platform_bitness() / "git" / "cmd" / "git.exe"); candidate_paths.push_back(Environment::get_ProgramFiles_32_bit() / "git" / "cmd" / "git.exe"); - if (auto ret = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version)) + const optional<fs::path> path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version); + if (auto p = path.get()) { - return *ret; + return *p; } return fetch_dependency(scripts_folder, L"git", downloaded_copy); |
