diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index 55e8334117..b17e81913e 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -33,7 +33,7 @@ jobs: container: wpilib/debian-base:trixie steps: - name: Install Dependencies - run: sudo apt-get update && sudo apt-get install -y libopencv-dev clang-18 ninja-build avahi-daemon + run: sudo apt-get update && sudo apt-get install -y libopencv-dev clang-19 ninja-build avahi-daemon - name: Install sccache uses: mozilla-actions/sccache-action@v0.0.10 @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@v6 - name: configure - run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-18 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-18 ${{ matrix.cmake-flags }} .. + run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-19 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-19 ${{ matrix.cmake-flags }} .. env: SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} diff --git a/.github/workflows/upstream-utils.yml b/.github/workflows/upstream-utils.yml index 10a675e2ed..0ce6e84129 100644 --- a/.github/workflows/upstream-utils.yml +++ b/.github/workflows/upstream-utils.yml @@ -60,12 +60,6 @@ jobs: ./eigen.py clone ./eigen.py copy-src ./eigen.py format-patch - - name: Run expected.py - run: | - cd upstream_utils - ./expected.py clone - ./expected.py copy-src - ./expected.py format-patch - name: Run fmt.py run: | cd upstream_utils diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index 7ff366da02..c40e9cf87f 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -21,7 +21,6 @@ paths = [ "wpiutil/src/main/native/include", "wpiutil/src/main/native/thirdparty/argparse/include", "wpiutil/src/main/native/thirdparty/debugging/include", - "wpiutil/src/main/native/thirdparty/expected/include", "wpiutil/src/main/native/thirdparty/fmtlib/include", "wpiutil/src/main/native/thirdparty/json/include", "wpiutil/src/main/native/thirdparty/llvm/include", diff --git a/glass/src/lib/native/cpp/support/ExpressionParser.cpp b/glass/src/lib/native/cpp/support/ExpressionParser.cpp index 54c7878407..710af13a25 100644 --- a/glass/src/lib/native/cpp/support/ExpressionParser.cpp +++ b/glass/src/lib/native/cpp/support/ExpressionParser.cpp @@ -5,12 +5,12 @@ #include "wpi/glass/support/ExpressionParser.hpp" #include +#include #include #include #include #include "wpi/util/StringExtras.hpp" -#include "wpi/util/expected" namespace wpi::glass::expression { @@ -219,17 +219,17 @@ std::optional ValueFromString(std::string_view str) { } template -wpi::util::expected EvalAll(std::stack& operStack, - std::stack& valStack) { +std::expected EvalAll(std::stack& operStack, + std::stack& valStack) { while (!operStack.empty()) { if (valStack.size() < 2) { - return wpi::util::unexpected("Missing operand"); + return std::unexpected("Missing operand"); } ApplyOperator(valStack, operStack.top()); operStack.pop(); } if (valStack.empty()) { - return wpi::util::unexpected("No value"); + return std::unexpected("No value"); } // Intentionally leaves the result value on top of valStack so unmatched @@ -238,7 +238,7 @@ wpi::util::expected EvalAll(std::stack& operStack, } template -wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { +std::expected ParseExpr(Lexer& lexer, bool insideParen) { std::stack operStack; std::stack valStack; @@ -257,7 +257,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { // is probably not what the user intended in this case, so give them an // error. if (prevType == TokenType::Number) { - return wpi::util::unexpected("Missing operator"); + return std::unexpected("Missing operator"); } // Implicit multiplication. Ex: "2(4 + 5)" @@ -270,7 +270,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { if (value) { valStack.push(value.value()); } else { - return wpi::util::unexpected("Invalid number"); + return std::unexpected("Invalid number"); } break; @@ -282,7 +282,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { operStack.push(Operator::Multiply); } - wpi::util::expected result = ParseExpr(lexer, true); + std::expected result = ParseExpr(lexer, true); if (!result) { return result; } @@ -293,7 +293,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { if (nextType == TokenType::End) { goto end; // Act as if closed at end of expression } - return wpi::util::unexpected("Expected )"); + return std::unexpected("Expected )"); } break; } @@ -307,8 +307,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { // Acts as if there was open paren at start of expression. EvalAll will // clear both stacks, and leave the result value on top of valStack. // This makes sure everything inside the parentheses is evaluated first - wpi::util::expected result = - EvalAll(operStack, valStack); + std::expected result = EvalAll(operStack, valStack); if (!result) { return result; } @@ -316,8 +315,8 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { } case TokenType::Error: - return wpi::util::unexpected(std::string("Unexpected character: ") - .append(token.str, token.strLen)); + return std::unexpected(std::string("Unexpected character: ") + .append(token.str, token.strLen)); default: Operator op = GetOperator(token.type); @@ -343,7 +342,7 @@ wpi::util::expected ParseExpr(Lexer& lexer, bool insideParen) { precedence < prevPrecedence) { operStack.pop(); if (valStack.size() < 2) { - return wpi::util::unexpected("Missing operand"); + return std::unexpected("Missing operand"); } ApplyOperator(valStack, prevOp); } else { @@ -364,13 +363,13 @@ end: // expr is null-terminated string, as ImGui::inputText() uses template -wpi::util::expected TryParseExpr(const char* expr) { +std::expected TryParseExpr(const char* expr) { Lexer lexer(expr, std::is_integral_v); return ParseExpr(lexer, false); } -template wpi::util::expected TryParseExpr(const char*); -template wpi::util::expected TryParseExpr(const char*); -template wpi::util::expected TryParseExpr(const char*); +template std::expected TryParseExpr(const char*); +template std::expected TryParseExpr(const char*); +template std::expected TryParseExpr(const char*); } // namespace wpi::glass::expression diff --git a/glass/src/lib/native/include/wpi/glass/support/ExpressionParser.hpp b/glass/src/lib/native/include/wpi/glass/support/ExpressionParser.hpp index 7d29343499..d4c67696b5 100644 --- a/glass/src/lib/native/include/wpi/glass/support/ExpressionParser.hpp +++ b/glass/src/lib/native/include/wpi/glass/support/ExpressionParser.hpp @@ -6,20 +6,16 @@ #include +#include #include -#include "wpi/util/expected" - namespace wpi::glass::expression { template -wpi::util::expected TryParseExpr(const char* expr); +std::expected TryParseExpr(const char* expr); -extern template wpi::util::expected TryParseExpr( - const char*); -extern template wpi::util::expected TryParseExpr( - const char*); -extern template wpi::util::expected TryParseExpr( - const char*); +extern template std::expected TryParseExpr(const char*); +extern template std::expected TryParseExpr(const char*); +extern template std::expected TryParseExpr(const char*); } // namespace wpi::glass::expression diff --git a/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp index 399cbe862a..35d2e5044a 100644 --- a/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" -#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -41,7 +41,7 @@ class DigitalHandleResource : public HandleBase { DigitalHandleResource(const DigitalHandleResource&) = delete; DigitalHandleResource& operator=(const DigitalHandleResource&) = delete; - wpi::util::expected>, HAL_Status> + std::expected>, HAL_Status> Allocate(int16_t index, HAL_HandleEnum enumValue, std::string_view name); int16_t GetIndex(THandle handle, HAL_HandleEnum enumValue) { return getHandleTypedIndex(handle, enumValue, m_version); @@ -56,23 +56,23 @@ class DigitalHandleResource : public HandleBase { }; template -wpi::util::expected>, HAL_Status> +std::expected>, HAL_Status> DigitalHandleResource::Allocate( int16_t index, HAL_HandleEnum enumValue, std::string_view name) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - return wpi::util::unexpected(MakeErrorIndexOutOfRange( - HAL_RESOURCE_OUT_OF_RANGE, name, 0, size, index)); + return std::unexpected(MakeErrorIndexOutOfRange(HAL_RESOURCE_OUT_OF_RANGE, + name, 0, size, index)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { if constexpr (detail::HasPreviousAllocation) { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index, m_structures[index]->previousAllocation)); } else { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index, "unknown")); } } diff --git a/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp index 59eae2741f..7bc407e092 100644 --- a/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp @@ -7,13 +7,13 @@ #include #include +#include #include #include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" -#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -42,9 +42,10 @@ class IndexedClassedHandleResource : public HandleBase { IndexedClassedHandleResource& operator=(const IndexedClassedHandleResource&) = delete; - wpi::util::expected Allocate( - int16_t index, std::shared_ptr toSet, std::string_view name, - int offset = 0); + std::expected Allocate(int16_t index, + std::shared_ptr toSet, + std::string_view name, + int offset = 0); int16_t GetIndex(THandle handle) { return getHandleTypedIndex(handle, enumValue, m_version); } @@ -59,25 +60,25 @@ class IndexedClassedHandleResource : public HandleBase { template -wpi::util::expected +std::expected IndexedClassedHandleResource::Allocate( int16_t index, std::shared_ptr toSet, std::string_view name, int offset) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - return wpi::util::unexpected( - MakeErrorIndexOutOfRange(HAL_RESOURCE_OUT_OF_RANGE, name, offset, - size + offset, index + offset)); + return std::unexpected(MakeErrorIndexOutOfRange(HAL_RESOURCE_OUT_OF_RANGE, + name, offset, size + offset, + index + offset)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { if constexpr (detail::HasPreviousAllocation) { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index + offset, m_structures[index]->previousAllocation)); } else { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index + offset, "unknown")); } } diff --git a/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp index 2eeef51916..23e432644f 100644 --- a/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" -#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -42,7 +42,7 @@ class IndexedHandleResource : public HandleBase { IndexedHandleResource(const IndexedHandleResource&) = delete; IndexedHandleResource& operator=(const IndexedHandleResource&) = delete; - wpi::util::expected>, HAL_Status> + std::expected>, HAL_Status> Allocate(int16_t index, std::string_view name, int offset = 0); int16_t GetIndex(THandle handle) { return getHandleTypedIndex(handle, enumValue, m_version); @@ -58,24 +58,24 @@ class IndexedHandleResource : public HandleBase { template -wpi::util::expected>, HAL_Status> +std::expected>, HAL_Status> IndexedHandleResource::Allocate( int16_t index, std::string_view name, int offset) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - return wpi::util::unexpected( - MakeErrorIndexOutOfRange(HAL_RESOURCE_OUT_OF_RANGE, name, offset, - size + offset, index + offset)); + return std::unexpected(MakeErrorIndexOutOfRange(HAL_RESOURCE_OUT_OF_RANGE, + name, offset, size + offset, + index + offset)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { if constexpr (detail::HasPreviousAllocation) { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index + offset, m_structures[index]->previousAllocation)); } else { - return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + return std::unexpected(MakeErrorPreviouslyAllocated( HAL_RESOURCE_IS_ALLOCATED, name, index + offset, "unknown")); } } diff --git a/ntcoreffi/BUILD.bazel b/ntcoreffi/BUILD.bazel index 26007e7bb5..25e5806bd2 100644 --- a/ntcoreffi/BUILD.bazel +++ b/ntcoreffi/BUILD.bazel @@ -39,7 +39,6 @@ wpilib_cc_library( "//wpiutil:wpiutil-hdrs-pkg", "//wpiutil:json-hdrs-pkg", "//wpiutil:mpack-hdrs-pkg", - "//wpiutil:expected-hdrs-pkg", "//wpiutil:debugging-hdrs-pkg", "//wpiutil:sigslot-hdrs-pkg", "//wpiutil:nanopb-hdrs-pkg", diff --git a/upstream_utils/expected.py b/upstream_utils/expected.py deleted file mode 100755 index 9c990cd9b2..0000000000 --- a/upstream_utils/expected.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -import shutil -from pathlib import Path - -from upstream_utils import Lib - - -def copy_upstream_src(wpilib_root: Path): - wpiutil = wpilib_root / "wpiutil" - - # Copy expected header into allwpilib - dest_filename = ( - wpiutil / "src/main/native/thirdparty/expected/include/wpi/util/expected" - ) - shutil.copyfile("include/tl/expected.hpp", dest_filename) - - # Rename namespace from tl to wpi, and detail to detail_expected - with open(dest_filename) as f: - content = f.read() - content = content.replace("namespace tl", "namespace wpi::util") - content = content.replace("tl::", "wpi::util::") - content = content.replace("TL_", "WPI_") - content = content.replace("namespace detail", "namespace detail_expected") - content = content.replace("detail::", "detail_expected::") - with open(dest_filename, "w") as f: - f.write(content) - - -def main(): - name = "expected" - url = "https://github.com/TartanLlama/expected" - # master on 2024-01-25 - tag = "3f0ca7b19253129700a073abfa6d8638d9f7c80c" - - expected = Lib(name, url, tag, copy_upstream_src) - expected.main() - - -if __name__ == "__main__": - main() diff --git a/upstream_utils/json_patches/0015-Change-parse-to-return-expected-with-error-string.patch b/upstream_utils/json_patches/0015-Change-parse-to-return-expected-with-error-string.patch index 3216c41c2e..764f2d1735 100644 --- a/upstream_utils/json_patches/0015-Change-parse-to-return-expected-with-error-string.patch +++ b/upstream_utils/json_patches/0015-Change-parse-to-return-expected-with-error-string.patch @@ -9,7 +9,7 @@ Subject: [PATCH 15/25] Change parse to return expected with error string 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/json.cpp b/json.cpp -index 2b4191865e84f4c160450fa8380ad578d37e1cd1..baefe6317126f95ec75fe9d9a896923d0a90e720 100644 +index 2b4191865e84f4c160450fa8380ad578d37e1cd1..11f2ccde854aed19724c991b36905b221e71ae84 100644 --- a/json.cpp +++ b/json.cpp @@ -1258,21 +1258,22 @@ json::parse(json& j, const char*& p, const char* e, int context, int depth) @@ -17,7 +17,7 @@ index 2b4191865e84f4c160450fa8380ad578d37e1cd1..baefe6317126f95ec75fe9d9a896923d } -std::pair -+wpi::util::expected ++std::expected json::parse(std::string_view s) { - json::Status s2; @@ -33,30 +33,30 @@ index 2b4191865e84f4c160450fa8380ad578d37e1cd1..baefe6317126f95ec75fe9d9a896923d + json j; + Status result = parse(j, p, e, 0, DEPTH); + if (result != success) { -+ return wpi::util::unexpected(StatusToString(result)); ++ return std::unexpected(StatusToString(result)); } - return res; + json j2; + Status s2 = parse(j2, p, e, 0, DEPTH); + if (s2 != absent_value) { -+ return wpi::util::unexpected(StatusToString(trailing_content)); ++ return std::unexpected(StatusToString(trailing_content)); + } + return j; } const char* diff --git a/json.h b/json.h -index 1c0dc26a460e17dab44f13d62059cf6e69f355c9..d2962c322678b0dd664707f34151094fec90d281 100644 +index 1c0dc26a460e17dab44f13d62059cf6e69f355c9..1553eecb7251d509622ab00a4ade4a672252845e 100644 --- a/json.h +++ b/json.h -@@ -22,6 +22,7 @@ +@@ -17,6 +17,7 @@ + + #pragma once + ++#include + #include + #include #include - - #include "wpi/util/StringMap.hpp" -+#include "wpi/util/expected" - - namespace wpi::util { - @@ -43,6 +44,7 @@ class json Object }; @@ -79,7 +79,7 @@ index 1c0dc26a460e17dab44f13d62059cf6e69f355c9..d2962c322678b0dd664707f34151094f public: - static const char* StatusToString(Status); - static std::pair parse(std::string_view); -+ static wpi::util::expected parse(std::string_view); ++ static std::expected parse(std::string_view); json(const json&); json(json&&); diff --git a/upstream_utils/json_patches/0016-Add-parse_or_throw.patch b/upstream_utils/json_patches/0016-Add-parse_or_throw.patch index 05ec3308ff..5b4f85900f 100644 --- a/upstream_utils/json_patches/0016-Add-parse_or_throw.patch +++ b/upstream_utils/json_patches/0016-Add-parse_or_throw.patch @@ -9,7 +9,7 @@ Subject: [PATCH 16/25] Add parse_or_throw 2 files changed, 11 insertions(+) diff --git a/json.cpp b/json.cpp -index baefe6317126f95ec75fe9d9a896923d0a90e720..49fbf92ea6e67e771f051f10b65ac795351c6f3d 100644 +index 11f2ccde854aed19724c991b36905b221e71ae84..84712da562ee6b1966bae788fbf32876eaec4cef 100644 --- a/json.cpp +++ b/json.cpp @@ -1276,6 +1276,16 @@ json::parse(std::string_view s) @@ -30,13 +30,13 @@ index baefe6317126f95ec75fe9d9a896923d0a90e720..49fbf92ea6e67e771f051f10b65ac795 json::StatusToString(json::Status status) { diff --git a/json.h b/json.h -index d2962c322678b0dd664707f34151094fec90d281..f42ba9c135cb76a1b0bc31f9e2c03b1ed7dce749 100644 +index 1553eecb7251d509622ab00a4ade4a672252845e..c5f39687e68289adadb988df9cfd81c031266859 100644 --- a/json.h +++ b/json.h @@ -96,6 +96,7 @@ class json public: - static wpi::util::expected parse(std::string_view); + static std::expected parse(std::string_view); + static json parse_or_throw(std::string_view); json(const json&); diff --git a/upstream_utils/json_patches/0017-Add-operator.patch b/upstream_utils/json_patches/0017-Add-operator.patch index 43f144c45f..d03372500c 100644 --- a/upstream_utils/json_patches/0017-Add-operator.patch +++ b/upstream_utils/json_patches/0017-Add-operator.patch @@ -9,7 +9,7 @@ Subject: [PATCH 17/25] Add operator== 2 files changed, 32 insertions(+) diff --git a/json.cpp b/json.cpp -index 49fbf92ea6e67e771f051f10b65ac795351c6f3d..40479bc266390f015e291b737b5751522dac76ac 100644 +index 84712da562ee6b1966bae788fbf32876eaec4cef..839c311017ccbb2f5ea8f85aab4965e9ce7af090 100644 --- a/json.cpp +++ b/json.cpp @@ -1361,4 +1361,30 @@ json::StatusToString(json::Status status) @@ -44,7 +44,7 @@ index 49fbf92ea6e67e771f051f10b65ac795351c6f3d..40479bc266390f015e291b737b575152 + } // namespace wpi::util diff --git a/json.h b/json.h -index f42ba9c135cb76a1b0bc31f9e2c03b1ed7dce749..fbc3fb959f71f6acc344f26247597959807d23bb 100644 +index c5f39687e68289adadb988df9cfd81c031266859..2f2bb7b3b0a265299a011e4e8011ea14065dca36 100644 --- a/json.h +++ b/json.h @@ -28,6 +28,7 @@ namespace wpi::util { diff --git a/upstream_utils/json_patches/0018-Add-container-functions.patch b/upstream_utils/json_patches/0018-Add-container-functions.patch index ac65028d6c..334334abbc 100644 --- a/upstream_utils/json_patches/0018-Add-container-functions.patch +++ b/upstream_utils/json_patches/0018-Add-container-functions.patch @@ -9,7 +9,7 @@ Subject: [PATCH 18/25] Add container functions 2 files changed, 120 insertions(+) diff --git a/json.cpp b/json.cpp -index 40479bc266390f015e291b737b5751522dac76ac..2307536b15be9aae19da4ec9370a5aa17d5150d1 100644 +index 839c311017ccbb2f5ea8f85aab4965e9ce7af090..a800ce44ab28117b957a2f7507908cbd4c730de9 100644 --- a/json.cpp +++ b/json.cpp @@ -606,6 +606,28 @@ json::contains(std::string_view key) const @@ -129,7 +129,7 @@ index 40479bc266390f015e291b737b5751522dac76ac..2307536b15be9aae19da4ec9370a5aa1 json::to_string() const { diff --git a/json.h b/json.h -index fbc3fb959f71f6acc344f26247597959807d23bb..62af49cb18b713304ad95e89c52f5cc5bbc4b626 100644 +index 2f2bb7b3b0a265299a011e4e8011ea14065dca36..b478523deea8ae3d852ebe369cea8ca60fdec01d 100644 --- a/json.h +++ b/json.h @@ -216,6 +216,9 @@ class json diff --git a/upstream_utils/json_patches/0019-Add-to_json-from_json-and-json_serializer-struct.patch b/upstream_utils/json_patches/0019-Add-to_json-from_json-and-json_serializer-struct.patch index cc1d9d78c1..3130c5b952 100644 --- a/upstream_utils/json_patches/0019-Add-to_json-from_json-and-json_serializer-struct.patch +++ b/upstream_utils/json_patches/0019-Add-to_json-from_json-and-json_serializer-struct.patch @@ -8,7 +8,7 @@ Subject: [PATCH 19/25] Add to_json, from_json, and json_serializer struct 1 file changed, 65 insertions(+) diff --git a/json.h b/json.h -index 62af49cb18b713304ad95e89c52f5cc5bbc4b626..e52435a79ee7537928ba59fb146f635fc8511bfc 100644 +index b478523deea8ae3d852ebe369cea8ca60fdec01d..d77ff1ea380614c54579d26cc233aa8424734b5b 100644 --- a/json.h +++ b/json.h @@ -26,6 +26,35 @@ diff --git a/upstream_utils/json_patches/0020-Add-array-and-object-factory-functions.patch b/upstream_utils/json_patches/0020-Add-array-and-object-factory-functions.patch index 0577234da9..45f23ff365 100644 --- a/upstream_utils/json_patches/0020-Add-array-and-object-factory-functions.patch +++ b/upstream_utils/json_patches/0020-Add-array-and-object-factory-functions.patch @@ -8,11 +8,11 @@ Subject: [PATCH 20/25] Add array and object factory functions 1 file changed, 30 insertions(+) diff --git a/json.h b/json.h -index e52435a79ee7537928ba59fb146f635fc8511bfc..6a52615ab3e1799ebcf51a3b5ca445b1e2e64b97 100644 +index d77ff1ea380614c54579d26cc233aa8424734b5b..08796527ea948c1cd602c0ba7a7b24dd75e57046 100644 --- a/json.h +++ b/json.h -@@ -19,6 +19,8 @@ - +@@ -20,6 +20,8 @@ + #include #include #include +#include diff --git a/upstream_utils/json_patches/0021-Add-array-constructor.patch b/upstream_utils/json_patches/0021-Add-array-constructor.patch index ebad63f003..01f467420c 100644 --- a/upstream_utils/json_patches/0021-Add-array-constructor.patch +++ b/upstream_utils/json_patches/0021-Add-array-constructor.patch @@ -8,14 +8,15 @@ Subject: [PATCH 21/25] Add array constructor 1 file changed, 21 insertions(+) diff --git a/json.h b/json.h -index 6a52615ab3e1799ebcf51a3b5ca445b1e2e64b97..ef3ea13b7cb147f0b383ff1ead496d495cfece32 100644 +index 08796527ea948c1cd602c0ba7a7b24dd75e57046..2dbf2cd9f8cc150c8f1dcfa7ef7ecd523b14d6ca 100644 --- a/json.h +++ b/json.h -@@ -17,6 +17,8 @@ +@@ -17,7 +17,9 @@ #pragma once +#include + #include +#include #include #include diff --git a/upstream_utils/json_patches/0022-Improve-stringize-and-marshal-and-use-raw_ostream.patch b/upstream_utils/json_patches/0022-Improve-stringize-and-marshal-and-use-raw_ostream.patch index 85e3a0cbe2..5b3ee8a17a 100644 --- a/upstream_utils/json_patches/0022-Improve-stringize-and-marshal-and-use-raw_ostream.patch +++ b/upstream_utils/json_patches/0022-Improve-stringize-and-marshal-and-use-raw_ostream.patch @@ -9,7 +9,7 @@ Subject: [PATCH 22/25] Improve stringize and marshal and use raw_ostream 2 files changed, 131 insertions(+), 87 deletions(-) diff --git a/json.cpp b/json.cpp -index 2307536b15be9aae19da4ec9370a5aa17d5150d1..1beec7cc30e90ab2e31bc488ee15cedf9a9f32e5 100644 +index a800ce44ab28117b957a2f7507908cbd4c730de9..b4a6689c2cf501abd884db0a8588e1042d2bac12 100644 --- a/json.cpp +++ b/json.cpp @@ -27,6 +27,7 @@ @@ -291,7 +291,7 @@ index 2307536b15be9aae19da4ec9370a5aa17d5150d1..1beec7cc30e90ab2e31bc488ee15cedf break; default: diff --git a/json.h b/json.h -index ef3ea13b7cb147f0b383ff1ead496d495cfece32..e42ee96ac8697eaf17fd9d5298e877a45a4644a0 100644 +index 2dbf2cd9f8cc150c8f1dcfa7ef7ecd523b14d6ca..a6a459fcda6015c2195b0a32611fc61525d5483c 100644 --- a/json.h +++ b/json.h @@ -31,6 +31,7 @@ diff --git a/upstream_utils/json_patches/0023-Update-include-path.patch b/upstream_utils/json_patches/0023-Update-include-path.patch index 168b22f5a1..e41c1665fe 100644 --- a/upstream_utils/json_patches/0023-Update-include-path.patch +++ b/upstream_utils/json_patches/0023-Update-include-path.patch @@ -8,7 +8,7 @@ Subject: [PATCH 23/25] Update include path 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json.cpp b/json.cpp -index 1beec7cc30e90ab2e31bc488ee15cedf9a9f32e5..f8416f3723df70032d274f32cda36b4ef1c7ed90 100644 +index b4a6689c2cf501abd884db0a8588e1042d2bac12..27fb732b5af7a5ded9971c767e96e3f4f79a6566 100644 --- a/json.cpp +++ b/json.cpp @@ -15,7 +15,7 @@ diff --git a/upstream_utils/json_patches/0024-Add-support-for-unsigned-long-long-values.patch b/upstream_utils/json_patches/0024-Add-support-for-unsigned-long-long-values.patch index 8aab172e8d..7107b51718 100644 --- a/upstream_utils/json_patches/0024-Add-support-for-unsigned-long-long-values.patch +++ b/upstream_utils/json_patches/0024-Add-support-for-unsigned-long-long-values.patch @@ -10,7 +10,7 @@ Make unsigned constructors constexpr 2 files changed, 112 insertions(+), 39 deletions(-) diff --git a/json.cpp b/json.cpp -index f8416f3723df70032d274f32cda36b4ef1c7ed90..7f23ece0e8fa09ccb5fef8226de39c55ef70efdd 100644 +index 27fb732b5af7a5ded9971c767e96e3f4f79a6566..c2a897f2ffe411fb6528741de1f4ea9e1a76a056 100644 --- a/json.cpp +++ b/json.cpp @@ -247,28 +247,6 @@ LongToString(char* p, long long x) @@ -218,7 +218,7 @@ index f8416f3723df70032d274f32cda36b4ef1c7ed90..7f23ece0e8fa09ccb5fef8226de39c55 return lhs.float_value == rhs.float_value; case json::Type::Double: diff --git a/json.h b/json.h -index e42ee96ac8697eaf17fd9d5298e877a45a4644a0..31c5ea39b67286df158a9d6e13ab5073498126b8 100644 +index a6a459fcda6015c2195b0a32611fc61525d5483c..ca7d76d837c9e0bdfb92e7c1b7bfd24cc8cb5ae2 100644 --- a/json.h +++ b/json.h @@ -17,6 +17,7 @@ @@ -227,8 +227,8 @@ index e42ee96ac8697eaf17fd9d5298e877a45a4644a0..31c5ea39b67286df158a9d6e13ab5073 +#include #include + #include #include - #include @@ -92,6 +93,7 @@ class json Null, Bool, diff --git a/upstream_utils/json_patches/0025-Make-bool-constructor-safe.patch b/upstream_utils/json_patches/0025-Make-bool-constructor-safe.patch index 61a2e11c05..7fea352c66 100644 --- a/upstream_utils/json_patches/0025-Make-bool-constructor-safe.patch +++ b/upstream_utils/json_patches/0025-Make-bool-constructor-safe.patch @@ -8,7 +8,7 @@ Subject: [PATCH 25/25] Make bool constructor safe 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json.h b/json.h -index 31c5ea39b67286df158a9d6e13ab5073498126b8..2746badf92a5bb4de6c38007d8e6dcfbed5b47eb 100644 +index ca7d76d837c9e0bdfb92e7c1b7bfd24cc8cb5ae2..cd9c52ba855c28bc4fd7316195bead50a709e184 100644 --- a/json.h +++ b/json.h @@ -167,7 +167,7 @@ class json diff --git a/wpimath/src/main/native/include/wpi/math/linalg/DARE.hpp b/wpimath/src/main/native/include/wpi/math/linalg/DARE.hpp index ec5a27606c..a612728b1d 100644 --- a/wpimath/src/main/native/include/wpi/math/linalg/DARE.hpp +++ b/wpimath/src/main/native/include/wpi/math/linalg/DARE.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include #include @@ -11,7 +12,6 @@ #include #include "wpi/math/system/LinearSystemUtil.hpp" -#include "wpi/util/expected" namespace wpi::math { @@ -166,7 +166,7 @@ Eigen::Matrix DARE( * @return Solution to the DARE on success, or DAREError on failure. */ template -wpi::util::expected, DAREError> DARE( +std::expected, DAREError> DARE( const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, @@ -175,20 +175,20 @@ wpi::util::expected, DAREError> DARE( if (checkPreconditions) { // Require R be symmetric if ((R - R.transpose()).norm() > 1e-10) { - return wpi::util::unexpected{DAREError::RNotSymmetric}; + return std::unexpected{DAREError::RNotSymmetric}; } } // Require R be positive definite auto R_llt = R.llt(); if (R_llt.info() != Eigen::Success) { - return wpi::util::unexpected{DAREError::RNotPositiveDefinite}; + return std::unexpected{DAREError::RNotPositiveDefinite}; } if (checkPreconditions) { // Require Q be symmetric if ((Q - Q.transpose()).norm() > 1e-10) { - return wpi::util::unexpected{DAREError::QNotSymmetric}; + return std::unexpected{DAREError::QNotSymmetric}; } // Require Q be positive semidefinite @@ -203,12 +203,12 @@ wpi::util::expected, DAREError> DARE( auto Q_ldlt = Q.ldlt(); if (Q_ldlt.info() != Eigen::Success || (Q_ldlt.vectorD().array() < 0.0).any()) { - return wpi::util::unexpected{DAREError::QNotPositiveSemidefinite}; + return std::unexpected{DAREError::QNotPositiveSemidefinite}; } // Require (A, B) pair be stabilizable if (!IsStabilizable(A, B)) { - return wpi::util::unexpected{DAREError::ABNotStabilizable}; + return std::unexpected{DAREError::ABNotStabilizable}; } // Require (A, C) pair be detectable where Q = CᵀC @@ -221,7 +221,7 @@ wpi::util::expected, DAREError> DARE( Q_ldlt.transpositionsP(); if (!IsDetectable(A, C)) { - return wpi::util::unexpected{DAREError::ACNotDetectable}; + return std::unexpected{DAREError::ACNotDetectable}; } } @@ -281,7 +281,7 @@ J = Σ [uₖ] [0 R][uₖ] ΔT @return Solution to the DARE on success, or DAREError on failure. */ template -wpi::util::expected, DAREError> DARE( +std::expected, DAREError> DARE( const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, @@ -291,14 +291,14 @@ wpi::util::expected, DAREError> DARE( if (checkPreconditions) { // Require R be symmetric if ((R - R.transpose()).norm() > 1e-10) { - return wpi::util::unexpected{DAREError::RNotSymmetric}; + return std::unexpected{DAREError::RNotSymmetric}; } } // Require R be positive definite auto R_llt = R.llt(); if (R_llt.info() != Eigen::Success) { - return wpi::util::unexpected{DAREError::RNotPositiveDefinite}; + return std::unexpected{DAREError::RNotPositiveDefinite}; } // This is a change of variables to make the DARE that includes Q, R, and N @@ -320,7 +320,7 @@ wpi::util::expected, DAREError> DARE( if (checkPreconditions) { // Require Q be symmetric if ((Q_2 - Q_2.transpose()).norm() > 1e-10) { - return wpi::util::unexpected{DAREError::QNotSymmetric}; + return std::unexpected{DAREError::QNotSymmetric}; } // Require Q be positive semidefinite @@ -335,12 +335,12 @@ wpi::util::expected, DAREError> DARE( auto Q_ldlt = Q_2.ldlt(); if (Q_ldlt.info() != Eigen::Success || (Q_ldlt.vectorD().array() < 0.0).any()) { - return wpi::util::unexpected{DAREError::QNotPositiveSemidefinite}; + return std::unexpected{DAREError::QNotPositiveSemidefinite}; } // Require (A, B) pair be stabilizable if (!IsStabilizable(A_2, B)) { - return wpi::util::unexpected{DAREError::ABNotStabilizable}; + return std::unexpected{DAREError::ABNotStabilizable}; } // Require (A, C) pair be detectable where Q = CᵀC @@ -353,7 +353,7 @@ wpi::util::expected, DAREError> DARE( Q_ldlt.transpositionsP(); if (!IsDetectable(A_2, C)) { - return wpi::util::unexpected{DAREError::ACNotDetectable}; + return std::unexpected{DAREError::ACNotDetectable}; } } diff --git a/wpimath/src/test/native/cpp/DARETest.cpp b/wpimath/src/test/native/cpp/DARETest.cpp index 4d354be4c4..91866a5c26 100644 --- a/wpimath/src/test/native/cpp/DARETest.cpp +++ b/wpimath/src/test/native/cpp/DARETest.cpp @@ -4,25 +4,24 @@ #include "wpi/math/linalg/DARE.hpp" +#include + #include #include #include #include "wpi/math/fmt/Eigen.hpp" #include "wpi/math/linalg/EigenCore.hpp" -#include "wpi/util/expected" #include "wpi/util/print.hpp" // 2x1 -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, @@ -31,15 +30,13 @@ wpi::math::DARE<2, 1>(const Eigen::Matrix& A, bool checkPreconditions); // 4x1 -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<4, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<4, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, @@ -48,15 +45,13 @@ wpi::math::DARE<4, 1>(const Eigen::Matrix& A, bool checkPreconditions); // 2x2 -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 2>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 2>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, @@ -65,15 +60,13 @@ wpi::math::DARE<2, 2>(const Eigen::Matrix& A, bool checkPreconditions); // 2x3 -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 3>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -extern template wpi::util::expected, - wpi::math::DAREError> +extern template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 3>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, diff --git a/wpimath/src/test/native/cpp/DARETest_Inst_2x1.cpp b/wpimath/src/test/native/cpp/DARETest_Inst_2x1.cpp index cbd37eafd0..dd2197cf6f 100644 --- a/wpimath/src/test/native/cpp/DARETest_Inst_2x1.cpp +++ b/wpimath/src/test/native/cpp/DARETest_Inst_2x1.cpp @@ -4,13 +4,13 @@ #include "wpi/math/linalg/DARE.hpp" -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, diff --git a/wpimath/src/test/native/cpp/DARETest_Inst_2x2.cpp b/wpimath/src/test/native/cpp/DARETest_Inst_2x2.cpp index 7f340eabc0..910b695a49 100644 --- a/wpimath/src/test/native/cpp/DARETest_Inst_2x2.cpp +++ b/wpimath/src/test/native/cpp/DARETest_Inst_2x2.cpp @@ -4,13 +4,13 @@ #include "wpi/math/linalg/DARE.hpp" -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 2>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 2>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, diff --git a/wpimath/src/test/native/cpp/DARETest_Inst_2x3.cpp b/wpimath/src/test/native/cpp/DARETest_Inst_2x3.cpp index 91f6bd8ffc..31a2f0eb11 100644 --- a/wpimath/src/test/native/cpp/DARETest_Inst_2x3.cpp +++ b/wpimath/src/test/native/cpp/DARETest_Inst_2x3.cpp @@ -4,13 +4,13 @@ #include "wpi/math/linalg/DARE.hpp" -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 3>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<2, 3>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, diff --git a/wpimath/src/test/native/cpp/DARETest_Inst_4x1.cpp b/wpimath/src/test/native/cpp/DARETest_Inst_4x1.cpp index 619488d1e5..0bac72439d 100644 --- a/wpimath/src/test/native/cpp/DARETest_Inst_4x1.cpp +++ b/wpimath/src/test/native/cpp/DARETest_Inst_4x1.cpp @@ -2,16 +2,17 @@ // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. -#include "wpi/math/linalg/DARE.hpp" -#include "wpi/util/expected" +#include -template wpi::util::expected, wpi::math::DAREError> +#include "wpi/math/linalg/DARE.hpp" + +template std::expected, wpi::math::DAREError> wpi::math::DARE<4, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, const Eigen::Matrix& R, bool checkPreconditions); -template wpi::util::expected, wpi::math::DAREError> +template std::expected, wpi::math::DAREError> wpi::math::DARE<4, 1>(const Eigen::Matrix& A, const Eigen::Matrix& B, const Eigen::Matrix& Q, diff --git a/wpiutil/BUILD.bazel b/wpiutil/BUILD.bazel index 0fadff6195..30585fc6fa 100644 --- a/wpiutil/BUILD.bazel +++ b/wpiutil/BUILD.bazel @@ -22,7 +22,6 @@ filegroup( "src/main/native/thirdparty/argparse/include/**/*", "src/main/native/thirdparty/debugging/include/**/*", "src/main/native/thirdparty/double-conversion/include/**/*", - "src/main/native/thirdparty/expected/include/**/*", "src/main/native/thirdparty/fmtlib/include/**/*", "src/main/native/thirdparty/json/include/**/*", "src/main/native/thirdparty/llvm/include/**/*", @@ -105,12 +104,6 @@ third_party_cc_lib_helper( visibility = ["//visibility:public"], ) -third_party_cc_lib_helper( - name = "expected", - include_root = "src/main/native/thirdparty/expected/include", - visibility = ["//visibility:public"], -) - third_party_cc_lib_helper( name = "fmtlib", include_root = "src/main/native/thirdparty/fmtlib/include", @@ -189,7 +182,6 @@ wpilib_cc_library( strip_include_prefix = "src/main/native/include", third_party_header_only_libraries = [ ":argparse", - ":expected", ":sigslot", ], third_party_libraries = [ @@ -366,7 +358,6 @@ generate_robotpy_native_wrapper_build_info( "argparse", "debugging", "double-conversion", - "expected", "fmtlib", "json", "llvm", diff --git a/wpiutil/CMakeLists.txt b/wpiutil/CMakeLists.txt index 57886008c1..7e5e035ffc 100644 --- a/wpiutil/CMakeLists.txt +++ b/wpiutil/CMakeLists.txt @@ -93,7 +93,6 @@ install( src/main/native/thirdparty/argparse/include/ src/main/native/thirdparty/debugging/include/ src/main/native/thirdparty/double-conversion/include/ - src/main/native/thirdparty/expected/include/ src/main/native/thirdparty/json/include/ src/main/native/thirdparty/llvm/include/ src/main/native/thirdparty/mpack/include/ @@ -109,7 +108,6 @@ target_include_directories( $ $ $ - $ $ $ $ diff --git a/wpiutil/build.gradle b/wpiutil/build.gradle index 1e142b5cf2..38e53a6ab0 100644 --- a/wpiutil/build.gradle +++ b/wpiutil/build.gradle @@ -48,7 +48,7 @@ ext { include '**/*.cpp' } exportedHeaders { - srcDirs 'src/main/native/include', 'src/main/native/thirdparty/double-conversion/include', 'src/main/native/thirdparty/expected/include', 'src/main/native/thirdparty/llvm/include', 'src/main/native/thirdparty/json/include' + srcDirs 'src/main/native/include', 'src/main/native/thirdparty/double-conversion/include', 'src/main/native/thirdparty/llvm/include', 'src/main/native/thirdparty/json/include' } } llvmCpp(CppSourceSet) { @@ -57,7 +57,7 @@ ext { include '**/*.cpp' } exportedHeaders { - srcDirs 'src/main/native/include', 'src/main/native/thirdparty/expected/include', 'src/main/native/thirdparty/fmtlib/include', 'src/main/native/thirdparty/llvm/include' + srcDirs 'src/main/native/include', 'src/main/native/thirdparty/fmtlib/include', 'src/main/native/thirdparty/llvm/include' } } mpackCpp(CppSourceSet) { @@ -156,7 +156,6 @@ cppHeadersZip { 'src/main/native/thirdparty/argparse/include', 'src/main/native/thirdparty/debugging/include', 'src/main/native/thirdparty/double-conversion/include', - 'src/main/native/thirdparty/expected/include', 'src/main/native/thirdparty/fmtlib/include', 'src/main/native/thirdparty/json/include', 'src/main/native/thirdparty/llvm/include', @@ -209,7 +208,7 @@ model { all { it.sources.each { it.exportedHeaders { - srcDirs 'src/main/native/include', 'src/main/native/thirdparty/argparse/include/', 'src/main/native/thirdparty/debugging/include', 'src/main/native/thirdparty/double-conversion/include', 'src/main/native/thirdparty/expected/include', 'src/main/native/thirdparty/fmtlib/include', 'src/main/native/thirdparty/llvm/include', 'src/main/native/thirdparty/sigslot/include', 'src/main/native/thirdparty/json/include', 'src/main/native/thirdparty/mpack/include', 'src/main/native/thirdparty/nanopb/include', 'src/main/native/thirdparty/upb/include' + srcDirs 'src/main/native/include', 'src/main/native/thirdparty/argparse/include/', 'src/main/native/thirdparty/debugging/include', 'src/main/native/thirdparty/double-conversion/include', 'src/main/native/thirdparty/fmtlib/include', 'src/main/native/thirdparty/llvm/include', 'src/main/native/thirdparty/sigslot/include', 'src/main/native/thirdparty/json/include', 'src/main/native/thirdparty/mpack/include', 'src/main/native/thirdparty/nanopb/include', 'src/main/native/thirdparty/upb/include' } } } diff --git a/wpiutil/robotpy_native_build_info.bzl b/wpiutil/robotpy_native_build_info.bzl index e6d22bf848..8a3be58209 100644 --- a/wpiutil/robotpy_native_build_info.bzl +++ b/wpiutil/robotpy_native_build_info.bzl @@ -12,7 +12,6 @@ def define_native_wrapper(name, pyproject_toml = None): "src/main/native/thirdparty/argparse/include/**", "src/main/native/thirdparty/debugging/include/**", "src/main/native/thirdparty/double-conversion/include/**", - "src/main/native/thirdparty/expected/include/**", "src/main/native/thirdparty/fmtlib/include/**", "src/main/native/thirdparty/json/include/**", "src/main/native/thirdparty/llvm/include/**", @@ -29,7 +28,6 @@ def define_native_wrapper(name, pyproject_toml = None): "wpiutil/src/main/native/thirdparty/argparse/include": "", "wpiutil/src/main/native/thirdparty/debugging/include": "", "wpiutil/src/main/native/thirdparty/double-conversion/include": "", - "wpiutil/src/main/native/thirdparty/expected/include": "", "wpiutil/src/main/native/thirdparty/fmtlib/include": "", "wpiutil/src/main/native/thirdparty/json/include": "", "wpiutil/src/main/native/thirdparty/llvm/include": "", diff --git a/wpiutil/src/main/native/thirdparty/expected/include/wpi/util/expected b/wpiutil/src/main/native/thirdparty/expected/include/wpi/util/expected deleted file mode 100644 index 168f97889c..0000000000 --- a/wpiutil/src/main/native/thirdparty/expected/include/wpi/util/expected +++ /dev/null @@ -1,2444 +0,0 @@ -/// -// expected - An implementation of std::expected with extensions -// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama) -// -// Documentation available at http://tl.tartanllama.xyz/ -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to the -// public domain worldwide. This software is distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. If not, see -// . -/// - -#ifndef WPI_EXPECTED_HPP -#define WPI_EXPECTED_HPP - -#define WPI_EXPECTED_VERSION_MAJOR 1 -#define WPI_EXPECTED_VERSION_MINOR 1 -#define WPI_EXPECTED_VERSION_PATCH 0 - -#include -#include -#include -#include - -#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) -#define WPI_EXPECTED_EXCEPTIONS_ENABLED -#endif - -#if (defined(_MSC_VER) && _MSC_VER == 1900) -#define WPI_EXPECTED_MSVC2015 -#define WPI_EXPECTED_MSVC2015_CONSTEXPR -#else -#define WPI_EXPECTED_MSVC2015_CONSTEXPR constexpr -#endif - -#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ - !defined(__clang__)) -#define WPI_EXPECTED_GCC49 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ - !defined(__clang__)) -#define WPI_EXPECTED_GCC54 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ - !defined(__clang__)) -#define WPI_EXPECTED_GCC55 -#endif - -#if !defined(WPI_ASSERT) -//can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug -#if (__cplusplus > 201103L) && !defined(WPI_EXPECTED_GCC49) -#include -#define WPI_ASSERT(x) assert(x) -#else -#define WPI_ASSERT(x) -#endif -#endif - -#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ - !defined(__clang__)) -// GCC < 5 doesn't support overloading on const&& for member functions - -#define WPI_EXPECTED_NO_CONSTRR -// GCC < 5 doesn't support some standard C++11 type traits -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - std::has_trivial_copy_constructor -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::has_trivial_copy_assign - -// This one will be different for GCC 5.7 if it's ever supported -#define WPI_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible - -// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks -// std::vector for non-copyable types -#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) -#ifndef WPI_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX -#define WPI_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX -namespace wpi::util { -namespace detail_expected { -template -struct is_trivially_copy_constructible - : std::is_trivially_copy_constructible {}; -#ifdef _GLIBCXX_VECTOR -template -struct is_trivially_copy_constructible> : std::false_type {}; -#endif -} // namespace detail_expected -} // namespace wpi::util -#endif - -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - wpi::util::detail_expected::is_trivially_copy_constructible -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::is_trivially_copy_assignable -#define WPI_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible -#else -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - std::is_trivially_copy_constructible -#define WPI_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::is_trivially_copy_assignable -#define WPI_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible -#endif - -#if __cplusplus > 201103L -#define WPI_EXPECTED_CXX14 -#endif - -#ifdef WPI_EXPECTED_GCC49 -#define WPI_EXPECTED_GCC49_CONSTEXPR -#else -#define WPI_EXPECTED_GCC49_CONSTEXPR constexpr -#endif - -#if (__cplusplus == 201103L || defined(WPI_EXPECTED_MSVC2015) || \ - defined(WPI_EXPECTED_GCC49)) -#define WPI_EXPECTED_11_CONSTEXPR -#else -#define WPI_EXPECTED_11_CONSTEXPR constexpr -#endif - -namespace wpi::util { -template class expected; - -#ifndef WPI_MONOSTATE_INPLACE_MUTEX -#define WPI_MONOSTATE_INPLACE_MUTEX -class monostate {}; - -struct in_place_t { - explicit in_place_t() = default; -}; -static constexpr in_place_t in_place{}; -#endif - -template class unexpected { -public: - static_assert(!std::is_same::value, "E must not be void"); - - unexpected() = delete; - constexpr explicit unexpected(const E &e) : m_val(e) {} - - constexpr explicit unexpected(E &&e) : m_val(std::move(e)) {} - - template ::value>::type * = nullptr> - constexpr explicit unexpected(Args &&...args) - : m_val(std::forward(args)...) {} - template < - class U, class... Args, - typename std::enable_if &, Args &&...>::value>::type * = nullptr> - constexpr explicit unexpected(std::initializer_list l, Args &&...args) - : m_val(l, std::forward(args)...) {} - - constexpr const E &value() const & { return m_val; } - WPI_EXPECTED_11_CONSTEXPR E &value() & { return m_val; } - WPI_EXPECTED_11_CONSTEXPR E &&value() && { return std::move(m_val); } - constexpr const E &&value() const && { return std::move(m_val); } - -private: - E m_val; -}; - -#ifdef __cpp_deduction_guides -template unexpected(E) -> unexpected; -#endif - -template -constexpr bool operator==(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() == rhs.value(); -} -template -constexpr bool operator!=(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() != rhs.value(); -} -template -constexpr bool operator<(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() < rhs.value(); -} -template -constexpr bool operator<=(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() <= rhs.value(); -} -template -constexpr bool operator>(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() > rhs.value(); -} -template -constexpr bool operator>=(const unexpected &lhs, const unexpected &rhs) { - return lhs.value() >= rhs.value(); -} - -template -unexpected::type> make_unexpected(E &&e) { - return unexpected::type>(std::forward(e)); -} - -struct unexpect_t { - unexpect_t() = default; -}; -static constexpr unexpect_t unexpect{}; - -namespace detail_expected { -template -[[noreturn]] WPI_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) { -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - throw std::forward(e); -#else - (void)e; -#ifdef _MSC_VER - __assume(0); -#else - __builtin_unreachable(); -#endif -#endif -} - -#ifndef WPI_TRAITS_MUTEX -#define WPI_TRAITS_MUTEX -// C++14-style aliases for brevity -template using remove_const_t = typename std::remove_const::type; -template -using remove_reference_t = typename std::remove_reference::type; -template using decay_t = typename std::decay::type; -template -using enable_if_t = typename std::enable_if::type; -template -using conditional_t = typename std::conditional::type; - -// std::conjunction from C++17 -template struct conjunction : std::true_type {}; -template struct conjunction : B {}; -template -struct conjunction - : std::conditional, B>::type {}; - -#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L -#define WPI_TRAITS_LIBCXX_MEM_FN_WORKAROUND -#endif - -// In C++11 mode, there's an issue in libc++'s std::mem_fn -// which results in a hard-error when using it in a noexcept expression -// in some cases. This is a check to workaround the common failing case. -#ifdef WPI_TRAITS_LIBCXX_MEM_FN_WORKAROUND -template -struct is_pointer_to_non_const_member_func : std::false_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; -template -struct is_pointer_to_non_const_member_func - : std::true_type {}; - -template struct is_const_or_const_ref : std::false_type {}; -template struct is_const_or_const_ref : std::true_type {}; -template struct is_const_or_const_ref : std::true_type {}; -#endif - -// std::invoke from C++17 -// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround -template < - typename Fn, typename... Args, -#ifdef WPI_TRAITS_LIBCXX_MEM_FN_WORKAROUND - typename = enable_if_t::value && - is_const_or_const_ref::value)>, -#endif - typename = enable_if_t>::value>, int = 0> -constexpr auto invoke(Fn &&f, Args &&...args) noexcept( - noexcept(std::mem_fn(f)(std::forward(args)...))) - -> decltype(std::mem_fn(f)(std::forward(args)...)) { - return std::mem_fn(f)(std::forward(args)...); -} - -template >::value>> -constexpr auto invoke(Fn &&f, Args &&...args) noexcept( - noexcept(std::forward(f)(std::forward(args)...))) - -> decltype(std::forward(f)(std::forward(args)...)) { - return std::forward(f)(std::forward(args)...); -} - -// std::invoke_result from C++17 -template struct invoke_result_impl; - -template -struct invoke_result_impl< - F, - decltype(detail_expected::invoke(std::declval(), std::declval()...), void()), - Us...> { - using type = - decltype(detail_expected::invoke(std::declval(), std::declval()...)); -}; - -template -using invoke_result = invoke_result_impl; - -template -using invoke_result_t = typename invoke_result::type; - -#if defined(_MSC_VER) && _MSC_VER <= 1900 -// TODO make a version which works with MSVC 2015 -template struct is_swappable : std::true_type {}; - -template struct is_nothrow_swappable : std::true_type {}; -#else -// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept -namespace swap_adl_tests { -// if swap ADL finds this then it would call std::swap otherwise (same -// signature) -struct tag {}; - -template tag swap(T &, T &); -template tag swap(T (&a)[N], T (&b)[N]); - -// helper functions to test if an unqualified swap is possible, and if it -// becomes std::swap -template std::false_type can_swap(...) noexcept(false); -template (), std::declval()))> -std::true_type can_swap(int) noexcept(noexcept(swap(std::declval(), - std::declval()))); - -template std::false_type uses_std(...); -template -std::is_same(), std::declval())), tag> -uses_std(int); - -template -struct is_std_swap_noexcept - : std::integral_constant::value && - std::is_nothrow_move_assignable::value> {}; - -template -struct is_std_swap_noexcept : is_std_swap_noexcept {}; - -template -struct is_adl_swap_noexcept - : std::integral_constant(0))> {}; -} // namespace swap_adl_tests - -template -struct is_swappable - : std::integral_constant< - bool, - decltype(detail_expected::swap_adl_tests::can_swap(0))::value && - (!decltype(detail_expected::swap_adl_tests::uses_std(0))::value || - (std::is_move_assignable::value && - std::is_move_constructible::value))> {}; - -template -struct is_swappable - : std::integral_constant< - bool, - decltype(detail_expected::swap_adl_tests::can_swap(0))::value && - (!decltype(detail_expected::swap_adl_tests::uses_std( - 0))::value || - is_swappable::value)> {}; - -template -struct is_nothrow_swappable - : std::integral_constant< - bool, - is_swappable::value && - ((decltype(detail_expected::swap_adl_tests::uses_std(0))::value && - detail_expected::swap_adl_tests::is_std_swap_noexcept::value) || - (!decltype(detail_expected::swap_adl_tests::uses_std(0))::value && - detail_expected::swap_adl_tests::is_adl_swap_noexcept::value))> {}; -#endif -#endif - -// Trait for checking if a type is a wpi::util::expected -template struct is_expected_impl : std::false_type {}; -template -struct is_expected_impl> : std::true_type {}; -template using is_expected = is_expected_impl>; - -template -using expected_enable_forward_value = detail_expected::enable_if_t< - std::is_constructible::value && - !std::is_same, in_place_t>::value && - !std::is_same, detail_expected::decay_t>::value && - !std::is_same, detail_expected::decay_t>::value>; - -template -using expected_enable_from_other = detail_expected::enable_if_t< - std::is_constructible::value && - std::is_constructible::value && - !std::is_constructible &>::value && - !std::is_constructible &&>::value && - !std::is_constructible &>::value && - !std::is_constructible &&>::value && - !std::is_convertible &, T>::value && - !std::is_convertible &&, T>::value && - !std::is_convertible &, T>::value && - !std::is_convertible &&, T>::value>; - -template -using is_void_or = conditional_t::value, std::true_type, U>; - -template -using is_copy_constructible_or_void = - is_void_or>; - -template -using is_move_constructible_or_void = - is_void_or>; - -template -using is_copy_assignable_or_void = is_void_or>; - -template -using is_move_assignable_or_void = is_void_or>; - -} // namespace detail_expected - -namespace detail_expected { -struct no_init_t {}; -static constexpr no_init_t no_init{}; - -// Implements the storage of the values, and ensures that the destructor is -// trivial if it can be. -// -// This specialization is for where neither `T` or `E` is trivially -// destructible, so the destructors must be called on destruction of the -// `expected` -template ::value, - bool = std::is_trivially_destructible::value> -struct expected_storage_base { - constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {} - - template ::value> * = - nullptr> - constexpr expected_storage_base(in_place_t, Args &&...args) - : m_val(std::forward(args)...), m_has_val(true) {} - - template &, Args &&...>::value> * = nullptr> - constexpr expected_storage_base(in_place_t, std::initializer_list il, - Args &&...args) - : m_val(il, std::forward(args)...), m_has_val(true) {} - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() { - if (m_has_val) { - m_val.~T(); - } else { - m_unexpect.~unexpected(); - } - } - union { - T m_val; - unexpected m_unexpect; - char m_no_init; - }; - bool m_has_val; -}; - -// This specialization is for when both `T` and `E` are trivially-destructible, -// so the destructor of the `expected` can be trivial. -template struct expected_storage_base { - constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {} - - template ::value> * = - nullptr> - constexpr expected_storage_base(in_place_t, Args &&...args) - : m_val(std::forward(args)...), m_has_val(true) {} - - template &, Args &&...>::value> * = nullptr> - constexpr expected_storage_base(in_place_t, std::initializer_list il, - Args &&...args) - : m_val(il, std::forward(args)...), m_has_val(true) {} - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() = default; - union { - T m_val; - unexpected m_unexpect; - char m_no_init; - }; - bool m_has_val; -}; - -// T is trivial, E is not. -template struct expected_storage_base { - constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - WPI_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) - : m_no_init(), m_has_val(false) {} - - template ::value> * = - nullptr> - constexpr expected_storage_base(in_place_t, Args &&...args) - : m_val(std::forward(args)...), m_has_val(true) {} - - template &, Args &&...>::value> * = nullptr> - constexpr expected_storage_base(in_place_t, std::initializer_list il, - Args &&...args) - : m_val(il, std::forward(args)...), m_has_val(true) {} - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() { - if (!m_has_val) { - m_unexpect.~unexpected(); - } - } - - union { - T m_val; - unexpected m_unexpect; - char m_no_init; - }; - bool m_has_val; -}; - -// E is trivial, T is not. -template struct expected_storage_base { - constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {} - - template ::value> * = - nullptr> - constexpr expected_storage_base(in_place_t, Args &&...args) - : m_val(std::forward(args)...), m_has_val(true) {} - - template &, Args &&...>::value> * = nullptr> - constexpr expected_storage_base(in_place_t, std::initializer_list il, - Args &&...args) - : m_val(il, std::forward(args)...), m_has_val(true) {} - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() { - if (m_has_val) { - m_val.~T(); - } - } - union { - T m_val; - unexpected m_unexpect; - char m_no_init; - }; - bool m_has_val; -}; - -// `T` is `void`, `E` is trivially-destructible -template struct expected_storage_base { - #if __GNUC__ <= 5 - //no constexpr for GCC 4/5 bug - #else - WPI_EXPECTED_MSVC2015_CONSTEXPR - #endif - expected_storage_base() : m_has_val(true) {} - - constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {} - - constexpr expected_storage_base(in_place_t) : m_has_val(true) {} - - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() = default; - struct dummy {}; - union { - unexpected m_unexpect; - dummy m_val; - }; - bool m_has_val; -}; - -// `T` is `void`, `E` is not trivially-destructible -template struct expected_storage_base { - constexpr expected_storage_base() : m_dummy(), m_has_val(true) {} - constexpr expected_storage_base(no_init_t) : m_dummy(), m_has_val(false) {} - - constexpr expected_storage_base(in_place_t) : m_dummy(), m_has_val(true) {} - - template ::value> * = - nullptr> - constexpr explicit expected_storage_base(unexpect_t, Args &&...args) - : m_unexpect(std::forward(args)...), m_has_val(false) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected_storage_base(unexpect_t, - std::initializer_list il, - Args &&...args) - : m_unexpect(il, std::forward(args)...), m_has_val(false) {} - - ~expected_storage_base() { - if (!m_has_val) { - m_unexpect.~unexpected(); - } - } - - union { - unexpected m_unexpect; - char m_dummy; - }; - bool m_has_val; -}; - -// This base class provides some handy member functions which can be used in -// further derived classes -template -struct expected_operations_base : expected_storage_base { - using expected_storage_base::expected_storage_base; - - template void construct(Args &&...args) noexcept { - new (std::addressof(this->m_val)) T(std::forward(args)...); - this->m_has_val = true; - } - - template void construct_with(Rhs &&rhs) noexcept { - new (std::addressof(this->m_val)) T(std::forward(rhs).get()); - this->m_has_val = true; - } - - template void construct_error(Args &&...args) noexcept { - new (std::addressof(this->m_unexpect)) - unexpected(std::forward(args)...); - this->m_has_val = false; - } - -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - - // These assign overloads ensure that the most efficient assignment - // implementation is used while maintaining the strong exception guarantee. - // The problematic case is where rhs has a value, but *this does not. - // - // This overload handles the case where we can just copy-construct `T` - // directly into place without throwing. - template ::value> - * = nullptr> - void assign(const expected_operations_base &rhs) noexcept { - if (!this->m_has_val && rhs.m_has_val) { - geterr().~unexpected(); - construct(rhs.get()); - } else { - assign_common(rhs); - } - } - - // This overload handles the case where we can attempt to create a copy of - // `T`, then no-throw move it into place if the copy was successful. - template ::value && - std::is_nothrow_move_constructible::value> - * = nullptr> - void assign(const expected_operations_base &rhs) noexcept { - if (!this->m_has_val && rhs.m_has_val) { - T tmp = rhs.get(); - geterr().~unexpected(); - construct(std::move(tmp)); - } else { - assign_common(rhs); - } - } - - // This overload is the worst-case, where we have to move-construct the - // unexpected value into temporary storage, then try to copy the T into place. - // If the construction succeeds, then everything is fine, but if it throws, - // then we move the old unexpected value back into place before rethrowing the - // exception. - template ::value && - !std::is_nothrow_move_constructible::value> - * = nullptr> - void assign(const expected_operations_base &rhs) { - if (!this->m_has_val && rhs.m_has_val) { - auto tmp = std::move(geterr()); - geterr().~unexpected(); - -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - construct(rhs.get()); - } catch (...) { - geterr() = std::move(tmp); - throw; - } -#else - construct(rhs.get()); -#endif - } else { - assign_common(rhs); - } - } - - // These overloads do the same as above, but for rvalues - template ::value> - * = nullptr> - void assign(expected_operations_base &&rhs) noexcept { - if (!this->m_has_val && rhs.m_has_val) { - geterr().~unexpected(); - construct(std::move(rhs).get()); - } else { - assign_common(std::move(rhs)); - } - } - - template ::value> - * = nullptr> - void assign(expected_operations_base &&rhs) { - if (!this->m_has_val && rhs.m_has_val) { - auto tmp = std::move(geterr()); - geterr().~unexpected(); -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - construct(std::move(rhs).get()); - } catch (...) { - geterr() = std::move(tmp); - throw; - } -#else - construct(std::move(rhs).get()); -#endif - } else { - assign_common(std::move(rhs)); - } - } - -#else - - // If exceptions are disabled then we can just copy-construct - void assign(const expected_operations_base &rhs) noexcept { - if (!this->m_has_val && rhs.m_has_val) { - geterr().~unexpected(); - construct(rhs.get()); - } else { - assign_common(rhs); - } - } - - void assign(expected_operations_base &&rhs) noexcept { - if (!this->m_has_val && rhs.m_has_val) { - geterr().~unexpected(); - construct(std::move(rhs).get()); - } else { - assign_common(std::move(rhs)); - } - } - -#endif - - // The common part of move/copy assigning - template void assign_common(Rhs &&rhs) { - if (this->m_has_val) { - if (rhs.m_has_val) { - get() = std::forward(rhs).get(); - } else { - destroy_val(); - construct_error(std::forward(rhs).geterr()); - } - } else { - if (!rhs.m_has_val) { - geterr() = std::forward(rhs).geterr(); - } - } - } - - bool has_value() const { return this->m_has_val; } - - WPI_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; } - constexpr const T &get() const & { return this->m_val; } - WPI_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); } -#ifndef WPI_EXPECTED_NO_CONSTRR - constexpr const T &&get() const && { return std::move(this->m_val); } -#endif - - WPI_EXPECTED_11_CONSTEXPR unexpected &geterr() & { - return this->m_unexpect; - } - constexpr const unexpected &geterr() const & { return this->m_unexpect; } - WPI_EXPECTED_11_CONSTEXPR unexpected &&geterr() && { - return std::move(this->m_unexpect); - } -#ifndef WPI_EXPECTED_NO_CONSTRR - constexpr const unexpected &&geterr() const && { - return std::move(this->m_unexpect); - } -#endif - - WPI_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); } -}; - -// This base class provides some handy member functions which can be used in -// further derived classes -template -struct expected_operations_base : expected_storage_base { - using expected_storage_base::expected_storage_base; - - template void construct() noexcept { this->m_has_val = true; } - - // This function doesn't use its argument, but needs it so that code in - // levels above this can work independently of whether T is void - template void construct_with(Rhs &&) noexcept { - this->m_has_val = true; - } - - template void construct_error(Args &&...args) noexcept { - new (std::addressof(this->m_unexpect)) - unexpected(std::forward(args)...); - this->m_has_val = false; - } - - template void assign(Rhs &&rhs) noexcept { - if (!this->m_has_val) { - if (rhs.m_has_val) { - geterr().~unexpected(); - construct(); - } else { - geterr() = std::forward(rhs).geterr(); - } - } else { - if (!rhs.m_has_val) { - construct_error(std::forward(rhs).geterr()); - } - } - } - - bool has_value() const { return this->m_has_val; } - - WPI_EXPECTED_11_CONSTEXPR unexpected &geterr() & { - return this->m_unexpect; - } - constexpr const unexpected &geterr() const & { return this->m_unexpect; } - WPI_EXPECTED_11_CONSTEXPR unexpected &&geterr() && { - return std::move(this->m_unexpect); - } -#ifndef WPI_EXPECTED_NO_CONSTRR - constexpr const unexpected &&geterr() const && { - return std::move(this->m_unexpect); - } -#endif - - WPI_EXPECTED_11_CONSTEXPR void destroy_val() { - // no-op - } -}; - -// This class manages conditionally having a trivial copy constructor -// This specialization is for when T and E are trivially copy constructible -template :: - value &&WPI_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value> -struct expected_copy_base : expected_operations_base { - using expected_operations_base::expected_operations_base; -}; - -// This specialization is for when T or E are not trivially copy constructible -template -struct expected_copy_base : expected_operations_base { - using expected_operations_base::expected_operations_base; - - expected_copy_base() = default; - expected_copy_base(const expected_copy_base &rhs) - : expected_operations_base(no_init) { - if (rhs.has_value()) { - this->construct_with(rhs); - } else { - this->construct_error(rhs.geterr()); - } - } - - expected_copy_base(expected_copy_base &&rhs) = default; - expected_copy_base &operator=(const expected_copy_base &rhs) = default; - expected_copy_base &operator=(expected_copy_base &&rhs) = default; -}; - -// This class manages conditionally having a trivial move constructor -// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it -// doesn't implement an analogue to std::is_trivially_move_constructible. We -// have to make do with a non-trivial move constructor even if T is trivially -// move constructible -#ifndef WPI_EXPECTED_GCC49 -template >::value - &&std::is_trivially_move_constructible::value> -struct expected_move_base : expected_copy_base { - using expected_copy_base::expected_copy_base; -}; -#else -template struct expected_move_base; -#endif -template -struct expected_move_base : expected_copy_base { - using expected_copy_base::expected_copy_base; - - expected_move_base() = default; - expected_move_base(const expected_move_base &rhs) = default; - - expected_move_base(expected_move_base &&rhs) noexcept( - std::is_nothrow_move_constructible::value) - : expected_copy_base(no_init) { - if (rhs.has_value()) { - this->construct_with(std::move(rhs)); - } else { - this->construct_error(std::move(rhs.geterr())); - } - } - expected_move_base &operator=(const expected_move_base &rhs) = default; - expected_move_base &operator=(expected_move_base &&rhs) = default; -}; - -// This class manages conditionally having a trivial copy assignment operator -template >::value - &&WPI_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value - &&WPI_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value - &&WPI_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value> -struct expected_copy_assign_base : expected_move_base { - using expected_move_base::expected_move_base; -}; - -template -struct expected_copy_assign_base : expected_move_base { - using expected_move_base::expected_move_base; - - expected_copy_assign_base() = default; - expected_copy_assign_base(const expected_copy_assign_base &rhs) = default; - - expected_copy_assign_base(expected_copy_assign_base &&rhs) = default; - expected_copy_assign_base &operator=(const expected_copy_assign_base &rhs) { - this->assign(rhs); - return *this; - } - expected_copy_assign_base & - operator=(expected_copy_assign_base &&rhs) = default; -}; - -// This class manages conditionally having a trivial move assignment operator -// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it -// doesn't implement an analogue to std::is_trivially_move_assignable. We have -// to make do with a non-trivial move assignment operator even if T is trivially -// move assignable -#ifndef WPI_EXPECTED_GCC49 -template , - std::is_trivially_move_constructible, - std::is_trivially_move_assignable>>:: - value &&std::is_trivially_destructible::value - &&std::is_trivially_move_constructible::value - &&std::is_trivially_move_assignable::value> -struct expected_move_assign_base : expected_copy_assign_base { - using expected_copy_assign_base::expected_copy_assign_base; -}; -#else -template struct expected_move_assign_base; -#endif - -template -struct expected_move_assign_base - : expected_copy_assign_base { - using expected_copy_assign_base::expected_copy_assign_base; - - expected_move_assign_base() = default; - expected_move_assign_base(const expected_move_assign_base &rhs) = default; - - expected_move_assign_base(expected_move_assign_base &&rhs) = default; - - expected_move_assign_base & - operator=(const expected_move_assign_base &rhs) = default; - - expected_move_assign_base & - operator=(expected_move_assign_base &&rhs) noexcept( - std::is_nothrow_move_constructible::value - &&std::is_nothrow_move_assignable::value) { - this->assign(std::move(rhs)); - return *this; - } -}; - -// expected_delete_ctor_base will conditionally delete copy and move -// constructors depending on whether T is copy/move constructible -template ::value && - std::is_copy_constructible::value), - bool EnableMove = (is_move_constructible_or_void::value && - std::is_move_constructible::value)> -struct expected_delete_ctor_base { - expected_delete_ctor_base() = default; - expected_delete_ctor_base(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default; - expected_delete_ctor_base & - operator=(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base & - operator=(expected_delete_ctor_base &&) noexcept = default; -}; - -template -struct expected_delete_ctor_base { - expected_delete_ctor_base() = default; - expected_delete_ctor_base(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete; - expected_delete_ctor_base & - operator=(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base & - operator=(expected_delete_ctor_base &&) noexcept = default; -}; - -template -struct expected_delete_ctor_base { - expected_delete_ctor_base() = default; - expected_delete_ctor_base(const expected_delete_ctor_base &) = delete; - expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default; - expected_delete_ctor_base & - operator=(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base & - operator=(expected_delete_ctor_base &&) noexcept = default; -}; - -template -struct expected_delete_ctor_base { - expected_delete_ctor_base() = default; - expected_delete_ctor_base(const expected_delete_ctor_base &) = delete; - expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete; - expected_delete_ctor_base & - operator=(const expected_delete_ctor_base &) = default; - expected_delete_ctor_base & - operator=(expected_delete_ctor_base &&) noexcept = default; -}; - -// expected_delete_assign_base will conditionally delete copy and move -// constructors depending on whether T and E are copy/move constructible + -// assignable -template ::value && - std::is_copy_constructible::value && - is_copy_assignable_or_void::value && - std::is_copy_assignable::value), - bool EnableMove = (is_move_constructible_or_void::value && - std::is_move_constructible::value && - is_move_assignable_or_void::value && - std::is_move_assignable::value)> -struct expected_delete_assign_base { - expected_delete_assign_base() = default; - expected_delete_assign_base(const expected_delete_assign_base &) = default; - expected_delete_assign_base(expected_delete_assign_base &&) noexcept = - default; - expected_delete_assign_base & - operator=(const expected_delete_assign_base &) = default; - expected_delete_assign_base & - operator=(expected_delete_assign_base &&) noexcept = default; -}; - -template -struct expected_delete_assign_base { - expected_delete_assign_base() = default; - expected_delete_assign_base(const expected_delete_assign_base &) = default; - expected_delete_assign_base(expected_delete_assign_base &&) noexcept = - default; - expected_delete_assign_base & - operator=(const expected_delete_assign_base &) = default; - expected_delete_assign_base & - operator=(expected_delete_assign_base &&) noexcept = delete; -}; - -template -struct expected_delete_assign_base { - expected_delete_assign_base() = default; - expected_delete_assign_base(const expected_delete_assign_base &) = default; - expected_delete_assign_base(expected_delete_assign_base &&) noexcept = - default; - expected_delete_assign_base & - operator=(const expected_delete_assign_base &) = delete; - expected_delete_assign_base & - operator=(expected_delete_assign_base &&) noexcept = default; -}; - -template -struct expected_delete_assign_base { - expected_delete_assign_base() = default; - expected_delete_assign_base(const expected_delete_assign_base &) = default; - expected_delete_assign_base(expected_delete_assign_base &&) noexcept = - default; - expected_delete_assign_base & - operator=(const expected_delete_assign_base &) = delete; - expected_delete_assign_base & - operator=(expected_delete_assign_base &&) noexcept = delete; -}; - -// This is needed to be able to construct the expected_default_ctor_base which -// follows, while still conditionally deleting the default constructor. -struct default_constructor_tag { - explicit constexpr default_constructor_tag() = default; -}; - -// expected_default_ctor_base will ensure that expected has a deleted default -// consturctor if T is not default constructible. -// This specialization is for when T is default constructible -template ::value || std::is_void::value> -struct expected_default_ctor_base { - constexpr expected_default_ctor_base() noexcept = default; - constexpr expected_default_ctor_base( - expected_default_ctor_base const &) noexcept = default; - constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept = - default; - expected_default_ctor_base & - operator=(expected_default_ctor_base const &) noexcept = default; - expected_default_ctor_base & - operator=(expected_default_ctor_base &&) noexcept = default; - - constexpr explicit expected_default_ctor_base(default_constructor_tag) {} -}; - -// This specialization is for when T is not default constructible -template struct expected_default_ctor_base { - constexpr expected_default_ctor_base() noexcept = delete; - constexpr expected_default_ctor_base( - expected_default_ctor_base const &) noexcept = default; - constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept = - default; - expected_default_ctor_base & - operator=(expected_default_ctor_base const &) noexcept = default; - expected_default_ctor_base & - operator=(expected_default_ctor_base &&) noexcept = default; - - constexpr explicit expected_default_ctor_base(default_constructor_tag) {} -}; -} // namespace detail_expected - -template class bad_expected_access : public std::exception { -public: - explicit bad_expected_access(E e) : m_val(std::move(e)) {} - - virtual const char *what() const noexcept override { - return "Bad expected access"; - } - - const E &error() const & { return m_val; } - E &error() & { return m_val; } - const E &&error() const && { return std::move(m_val); } - E &&error() && { return std::move(m_val); } - -private: - E m_val; -}; - -/// An `expected` object is an object that contains the storage for -/// another object and manages the lifetime of this contained object `T`. -/// Alternatively it could contain the storage for another unexpected object -/// `E`. The contained object may not be initialized after the expected object -/// has been initialized, and may not be destroyed before the expected object -/// has been destroyed. The initialization state of the contained object is -/// tracked by the expected object. -template -class expected : private detail_expected::expected_move_assign_base, - private detail_expected::expected_delete_ctor_base, - private detail_expected::expected_delete_assign_base, - private detail_expected::expected_default_ctor_base { - static_assert(!std::is_reference::value, "T must not be a reference"); - static_assert(!std::is_same::type>::value, - "T must not be in_place_t"); - static_assert(!std::is_same::type>::value, - "T must not be unexpect_t"); - static_assert( - !std::is_same>::type>::value, - "T must not be unexpected"); - static_assert(!std::is_reference::value, "E must not be a reference"); - - T *valptr() { return std::addressof(this->m_val); } - const T *valptr() const { return std::addressof(this->m_val); } - unexpected *errptr() { return std::addressof(this->m_unexpect); } - const unexpected *errptr() const { - return std::addressof(this->m_unexpect); - } - - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR U &val() { - return this->m_val; - } - WPI_EXPECTED_11_CONSTEXPR unexpected &err() { return this->m_unexpect; } - - template ::value> * = nullptr> - constexpr const U &val() const { - return this->m_val; - } - constexpr const unexpected &err() const { return this->m_unexpect; } - - using impl_base = detail_expected::expected_move_assign_base; - using ctor_base = detail_expected::expected_default_ctor_base; - -public: - typedef T value_type; - typedef E error_type; - typedef unexpected unexpected_type; - -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) - template WPI_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { - return and_then_impl(*this, std::forward(f)); - } - template WPI_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { - return and_then_impl(std::move(*this), std::forward(f)); - } - template constexpr auto and_then(F &&f) const & { - return and_then_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template constexpr auto and_then(F &&f) const && { - return and_then_impl(std::move(*this), std::forward(f)); - } -#endif - -#else - template - WPI_EXPECTED_11_CONSTEXPR auto - and_then(F &&f) & -> decltype(and_then_impl(std::declval(), - std::forward(f))) { - return and_then_impl(*this, std::forward(f)); - } - template - WPI_EXPECTED_11_CONSTEXPR auto - and_then(F &&f) && -> decltype(and_then_impl(std::declval(), - std::forward(f))) { - return and_then_impl(std::move(*this), std::forward(f)); - } - template - constexpr auto and_then(F &&f) const & -> decltype(and_then_impl( - std::declval(), std::forward(f))) { - return and_then_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template - constexpr auto and_then(F &&f) const && -> decltype(and_then_impl( - std::declval(), std::forward(f))) { - return and_then_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) - template WPI_EXPECTED_11_CONSTEXPR auto map(F &&f) & { - return expected_map_impl(*this, std::forward(f)); - } - template WPI_EXPECTED_11_CONSTEXPR auto map(F &&f) && { - return expected_map_impl(std::move(*this), std::forward(f)); - } - template constexpr auto map(F &&f) const & { - return expected_map_impl(*this, std::forward(f)); - } - template constexpr auto map(F &&f) const && { - return expected_map_impl(std::move(*this), std::forward(f)); - } -#else - template - WPI_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( - std::declval(), std::declval())) - map(F &&f) & { - return expected_map_impl(*this, std::forward(f)); - } - template - WPI_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval(), - std::declval())) - map(F &&f) && { - return expected_map_impl(std::move(*this), std::forward(f)); - } - template - constexpr decltype(expected_map_impl(std::declval(), - std::declval())) - map(F &&f) const & { - return expected_map_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template - constexpr decltype(expected_map_impl(std::declval(), - std::declval())) - map(F &&f) const && { - return expected_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) - template WPI_EXPECTED_11_CONSTEXPR auto transform(F &&f) & { - return expected_map_impl(*this, std::forward(f)); - } - template WPI_EXPECTED_11_CONSTEXPR auto transform(F &&f) && { - return expected_map_impl(std::move(*this), std::forward(f)); - } - template constexpr auto transform(F &&f) const & { - return expected_map_impl(*this, std::forward(f)); - } - template constexpr auto transform(F &&f) const && { - return expected_map_impl(std::move(*this), std::forward(f)); - } -#else - template - WPI_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( - std::declval(), std::declval())) - transform(F &&f) & { - return expected_map_impl(*this, std::forward(f)); - } - template - WPI_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval(), - std::declval())) - transform(F &&f) && { - return expected_map_impl(std::move(*this), std::forward(f)); - } - template - constexpr decltype(expected_map_impl(std::declval(), - std::declval())) - transform(F &&f) const & { - return expected_map_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template - constexpr decltype(expected_map_impl(std::declval(), - std::declval())) - transform(F &&f) const && { - return expected_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) - template WPI_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & { - return map_error_impl(*this, std::forward(f)); - } - template WPI_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && { - return map_error_impl(std::move(*this), std::forward(f)); - } - template constexpr auto map_error(F &&f) const & { - return map_error_impl(*this, std::forward(f)); - } - template constexpr auto map_error(F &&f) const && { - return map_error_impl(std::move(*this), std::forward(f)); - } -#else - template - WPI_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval(), - std::declval())) - map_error(F &&f) & { - return map_error_impl(*this, std::forward(f)); - } - template - WPI_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval(), - std::declval())) - map_error(F &&f) && { - return map_error_impl(std::move(*this), std::forward(f)); - } - template - constexpr decltype(map_error_impl(std::declval(), - std::declval())) - map_error(F &&f) const & { - return map_error_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template - constexpr decltype(map_error_impl(std::declval(), - std::declval())) - map_error(F &&f) const && { - return map_error_impl(std::move(*this), std::forward(f)); - } -#endif -#endif -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) - template WPI_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { - return map_error_impl(*this, std::forward(f)); - } - template WPI_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { - return map_error_impl(std::move(*this), std::forward(f)); - } - template constexpr auto transform_error(F &&f) const & { - return map_error_impl(*this, std::forward(f)); - } - template constexpr auto transform_error(F &&f) const && { - return map_error_impl(std::move(*this), std::forward(f)); - } -#else - template - WPI_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval(), - std::declval())) - transform_error(F &&f) & { - return map_error_impl(*this, std::forward(f)); - } - template - WPI_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval(), - std::declval())) - transform_error(F &&f) && { - return map_error_impl(std::move(*this), std::forward(f)); - } - template - constexpr decltype(map_error_impl(std::declval(), - std::declval())) - transform_error(F &&f) const & { - return map_error_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template - constexpr decltype(map_error_impl(std::declval(), - std::declval())) - transform_error(F &&f) const && { - return map_error_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - template expected WPI_EXPECTED_11_CONSTEXPR or_else(F &&f) & { - return or_else_impl(*this, std::forward(f)); - } - - template expected WPI_EXPECTED_11_CONSTEXPR or_else(F &&f) && { - return or_else_impl(std::move(*this), std::forward(f)); - } - - template expected constexpr or_else(F &&f) const & { - return or_else_impl(*this, std::forward(f)); - } - -#ifndef WPI_EXPECTED_NO_CONSTRR - template expected constexpr or_else(F &&f) const && { - return or_else_impl(std::move(*this), std::forward(f)); - } -#endif - constexpr expected() = default; - constexpr expected(const expected &rhs) = default; - constexpr expected(expected &&rhs) = default; - expected &operator=(const expected &rhs) = default; - expected &operator=(expected &&rhs) = default; - - template ::value> * = - nullptr> - constexpr expected(in_place_t, Args &&...args) - : impl_base(in_place, std::forward(args)...), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template &, Args &&...>::value> * = nullptr> - constexpr expected(in_place_t, std::initializer_list il, Args &&...args) - : impl_base(in_place, il, std::forward(args)...), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template ::value> * = - nullptr, - detail_expected::enable_if_t::value> * = - nullptr> - explicit constexpr expected(const unexpected &e) - : impl_base(unexpect, e.value()), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template < - class G = E, - detail_expected::enable_if_t::value> * = - nullptr, - detail_expected::enable_if_t::value> * = nullptr> - constexpr expected(unexpected const &e) - : impl_base(unexpect, e.value()), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template < - class G = E, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::enable_if_t::value> * = nullptr> - explicit constexpr expected(unexpected &&e) noexcept( - std::is_nothrow_constructible::value) - : impl_base(unexpect, std::move(e.value())), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template < - class G = E, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::enable_if_t::value> * = nullptr> - constexpr expected(unexpected &&e) noexcept( - std::is_nothrow_constructible::value) - : impl_base(unexpect, std::move(e.value())), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template ::value> * = - nullptr> - constexpr explicit expected(unexpect_t, Args &&...args) - : impl_base(unexpect, std::forward(args)...), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template &, Args &&...>::value> * = nullptr> - constexpr explicit expected(unexpect_t, std::initializer_list il, - Args &&...args) - : impl_base(unexpect, il, std::forward(args)...), - ctor_base(detail_expected::default_constructor_tag{}) {} - - template ::value && - std::is_convertible::value)> * = - nullptr, - detail_expected::expected_enable_from_other - * = nullptr> - explicit WPI_EXPECTED_11_CONSTEXPR expected(const expected &rhs) - : ctor_base(detail_expected::default_constructor_tag{}) { - if (rhs.has_value()) { - this->construct(*rhs); - } else { - this->construct_error(rhs.error()); - } - } - - template ::value && - std::is_convertible::value)> * = - nullptr, - detail_expected::expected_enable_from_other - * = nullptr> - WPI_EXPECTED_11_CONSTEXPR expected(const expected &rhs) - : ctor_base(detail_expected::default_constructor_tag{}) { - if (rhs.has_value()) { - this->construct(*rhs); - } else { - this->construct_error(rhs.error()); - } - } - - template < - class U, class G, - detail_expected::enable_if_t::value && - std::is_convertible::value)> * = nullptr, - detail_expected::expected_enable_from_other * = nullptr> - explicit WPI_EXPECTED_11_CONSTEXPR expected(expected &&rhs) - : ctor_base(detail_expected::default_constructor_tag{}) { - if (rhs.has_value()) { - this->construct(std::move(*rhs)); - } else { - this->construct_error(std::move(rhs.error())); - } - } - - template < - class U, class G, - detail_expected::enable_if_t<(std::is_convertible::value && - std::is_convertible::value)> * = nullptr, - detail_expected::expected_enable_from_other * = nullptr> - WPI_EXPECTED_11_CONSTEXPR expected(expected &&rhs) - : ctor_base(detail_expected::default_constructor_tag{}) { - if (rhs.has_value()) { - this->construct(std::move(*rhs)); - } else { - this->construct_error(std::move(rhs.error())); - } - } - - template < - class U = T, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::expected_enable_forward_value * = nullptr> - explicit WPI_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) - : expected(in_place, std::forward(v)) {} - - template < - class U = T, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::expected_enable_forward_value * = nullptr> - WPI_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) - : expected(in_place, std::forward(v)) {} - - template < - class U = T, class G = T, - detail_expected::enable_if_t::value> * = - nullptr, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::enable_if_t< - (!std::is_same, detail_expected::decay_t>::value && - !detail_expected::conjunction, - std::is_same>>::value && - std::is_constructible::value && - std::is_assignable::value && - std::is_nothrow_move_constructible::value)> * = nullptr> - expected &operator=(U &&v) { - if (has_value()) { - val() = std::forward(v); - } else { - err().~unexpected(); - ::new (valptr()) T(std::forward(v)); - this->m_has_val = true; - } - - return *this; - } - - template < - class U = T, class G = T, - detail_expected::enable_if_t::value> * = - nullptr, - detail_expected::enable_if_t::value> * = nullptr, - detail_expected::enable_if_t< - (!std::is_same, detail_expected::decay_t>::value && - !detail_expected::conjunction, - std::is_same>>::value && - std::is_constructible::value && - std::is_assignable::value && - std::is_nothrow_move_constructible::value)> * = nullptr> - expected &operator=(U &&v) { - if (has_value()) { - val() = std::forward(v); - } else { - auto tmp = std::move(err()); - err().~unexpected(); - -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - ::new (valptr()) T(std::forward(v)); - this->m_has_val = true; - } catch (...) { - err() = std::move(tmp); - throw; - } -#else - ::new (valptr()) T(std::forward(v)); - this->m_has_val = true; -#endif - } - - return *this; - } - - template ::value && - std::is_assignable::value> * = nullptr> - expected &operator=(const unexpected &rhs) { - if (!has_value()) { - err() = rhs; - } else { - this->destroy_val(); - ::new (errptr()) unexpected(rhs); - this->m_has_val = false; - } - - return *this; - } - - template ::value && - std::is_move_assignable::value> * = nullptr> - expected &operator=(unexpected &&rhs) noexcept { - if (!has_value()) { - err() = std::move(rhs); - } else { - this->destroy_val(); - ::new (errptr()) unexpected(std::move(rhs)); - this->m_has_val = false; - } - - return *this; - } - - template ::value> * = nullptr> - void emplace(Args &&...args) { - if (has_value()) { - val().~T(); - } else { - err().~unexpected(); - this->m_has_val = true; - } - ::new (valptr()) T(std::forward(args)...); - } - - template ::value> * = nullptr> - void emplace(Args &&...args) { - if (has_value()) { - val().~T(); - ::new (valptr()) T(std::forward(args)...); - } else { - auto tmp = std::move(err()); - err().~unexpected(); - -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - ::new (valptr()) T(std::forward(args)...); - this->m_has_val = true; - } catch (...) { - err() = std::move(tmp); - throw; - } -#else - ::new (valptr()) T(std::forward(args)...); - this->m_has_val = true; -#endif - } - } - - template &, Args &&...>::value> * = nullptr> - void emplace(std::initializer_list il, Args &&...args) { - if (has_value()) { - T t(il, std::forward(args)...); - val() = std::move(t); - } else { - err().~unexpected(); - ::new (valptr()) T(il, std::forward(args)...); - this->m_has_val = true; - } - } - - template &, Args &&...>::value> * = nullptr> - void emplace(std::initializer_list il, Args &&...args) { - if (has_value()) { - T t(il, std::forward(args)...); - val() = std::move(t); - } else { - auto tmp = std::move(err()); - err().~unexpected(); - -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - ::new (valptr()) T(il, std::forward(args)...); - this->m_has_val = true; - } catch (...) { - err() = std::move(tmp); - throw; - } -#else - ::new (valptr()) T(il, std::forward(args)...); - this->m_has_val = true; -#endif - } - } - -private: - using t_is_void = std::true_type; - using t_is_not_void = std::false_type; - using t_is_nothrow_move_constructible = std::true_type; - using move_constructing_t_can_throw = std::false_type; - using e_is_nothrow_move_constructible = std::true_type; - using move_constructing_e_can_throw = std::false_type; - - void swap_where_both_have_value(expected & /*rhs*/, t_is_void) noexcept { - // swapping void is a no-op - } - - void swap_where_both_have_value(expected &rhs, t_is_not_void) { - using std::swap; - swap(val(), rhs.val()); - } - - void swap_where_only_one_has_value(expected &rhs, t_is_void) noexcept( - std::is_nothrow_move_constructible::value) { - ::new (errptr()) unexpected_type(std::move(rhs.err())); - rhs.err().~unexpected_type(); - std::swap(this->m_has_val, rhs.m_has_val); - } - - void swap_where_only_one_has_value(expected &rhs, t_is_not_void) { - swap_where_only_one_has_value_and_t_is_not_void( - rhs, typename std::is_nothrow_move_constructible::type{}, - typename std::is_nothrow_move_constructible::type{}); - } - - void swap_where_only_one_has_value_and_t_is_not_void( - expected &rhs, t_is_nothrow_move_constructible, - e_is_nothrow_move_constructible) noexcept { - auto temp = std::move(val()); - val().~T(); - ::new (errptr()) unexpected_type(std::move(rhs.err())); - rhs.err().~unexpected_type(); - ::new (rhs.valptr()) T(std::move(temp)); - std::swap(this->m_has_val, rhs.m_has_val); - } - - void swap_where_only_one_has_value_and_t_is_not_void( - expected &rhs, t_is_nothrow_move_constructible, - move_constructing_e_can_throw) { - auto temp = std::move(val()); - val().~T(); -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - ::new (errptr()) unexpected_type(std::move(rhs.err())); - rhs.err().~unexpected_type(); - ::new (rhs.valptr()) T(std::move(temp)); - std::swap(this->m_has_val, rhs.m_has_val); - } catch (...) { - val() = std::move(temp); - throw; - } -#else - ::new (errptr()) unexpected_type(std::move(rhs.err())); - rhs.err().~unexpected_type(); - ::new (rhs.valptr()) T(std::move(temp)); - std::swap(this->m_has_val, rhs.m_has_val); -#endif - } - - void swap_where_only_one_has_value_and_t_is_not_void( - expected &rhs, move_constructing_t_can_throw, - e_is_nothrow_move_constructible) { - auto temp = std::move(rhs.err()); - rhs.err().~unexpected_type(); -#ifdef WPI_EXPECTED_EXCEPTIONS_ENABLED - try { - ::new (rhs.valptr()) T(std::move(val())); - val().~T(); - ::new (errptr()) unexpected_type(std::move(temp)); - std::swap(this->m_has_val, rhs.m_has_val); - } catch (...) { - rhs.err() = std::move(temp); - throw; - } -#else - ::new (rhs.valptr()) T(std::move(val())); - val().~T(); - ::new (errptr()) unexpected_type(std::move(temp)); - std::swap(this->m_has_val, rhs.m_has_val); -#endif - } - -public: - template - detail_expected::enable_if_t::value && - detail_expected::is_swappable::value && - (std::is_nothrow_move_constructible::value || - std::is_nothrow_move_constructible::value)> - swap(expected &rhs) noexcept( - std::is_nothrow_move_constructible::value - &&detail_expected::is_nothrow_swappable::value - &&std::is_nothrow_move_constructible::value - &&detail_expected::is_nothrow_swappable::value) { - if (has_value() && rhs.has_value()) { - swap_where_both_have_value(rhs, typename std::is_void::type{}); - } else if (!has_value() && rhs.has_value()) { - rhs.swap(*this); - } else if (has_value()) { - swap_where_only_one_has_value(rhs, typename std::is_void::type{}); - } else { - using std::swap; - swap(err(), rhs.err()); - } - } - - constexpr const T *operator->() const { - WPI_ASSERT(has_value()); - return valptr(); - } - WPI_EXPECTED_11_CONSTEXPR T *operator->() { - WPI_ASSERT(has_value()); - return valptr(); - } - - template ::value> * = nullptr> - constexpr const U &operator*() const & { - WPI_ASSERT(has_value()); - return val(); - } - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR U &operator*() & { - WPI_ASSERT(has_value()); - return val(); - } - template ::value> * = nullptr> - constexpr const U &&operator*() const && { - WPI_ASSERT(has_value()); - return std::move(val()); - } - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR U &&operator*() && { - WPI_ASSERT(has_value()); - return std::move(val()); - } - - constexpr bool has_value() const noexcept { return this->m_has_val; } - constexpr explicit operator bool() const noexcept { return this->m_has_val; } - - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR const U &value() const & { - if (!has_value()) - detail_expected::throw_exception(bad_expected_access(err().value())); - return val(); - } - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR U &value() & { - if (!has_value()) - detail_expected::throw_exception(bad_expected_access(err().value())); - return val(); - } - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR const U &&value() const && { - if (!has_value()) - detail_expected::throw_exception(bad_expected_access(std::move(err()).value())); - return std::move(val()); - } - template ::value> * = nullptr> - WPI_EXPECTED_11_CONSTEXPR U &&value() && { - if (!has_value()) - detail_expected::throw_exception(bad_expected_access(std::move(err()).value())); - return std::move(val()); - } - - constexpr const E &error() const & { - WPI_ASSERT(!has_value()); - return err().value(); - } - WPI_EXPECTED_11_CONSTEXPR E &error() & { - WPI_ASSERT(!has_value()); - return err().value(); - } - constexpr const E &&error() const && { - WPI_ASSERT(!has_value()); - return std::move(err().value()); - } - WPI_EXPECTED_11_CONSTEXPR E &&error() && { - WPI_ASSERT(!has_value()); - return std::move(err().value()); - } - - template constexpr T value_or(U &&v) const & { - static_assert(std::is_copy_constructible::value && - std::is_convertible::value, - "T must be copy-constructible and convertible to from U&&"); - return bool(*this) ? **this : static_cast(std::forward(v)); - } - template WPI_EXPECTED_11_CONSTEXPR T value_or(U &&v) && { - static_assert(std::is_move_constructible::value && - std::is_convertible::value, - "T must be move-constructible and convertible to from U&&"); - return bool(*this) ? std::move(**this) : static_cast(std::forward(v)); - } -}; - -namespace detail_expected { -template using exp_t = typename detail_expected::decay_t::value_type; -template using err_t = typename detail_expected::decay_t::error_type; -template using ret_t = expected>; - -#ifdef WPI_EXPECTED_CXX14 -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - *std::declval()))> -constexpr auto and_then_impl(Exp &&exp, F &&f) { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - - return exp.has_value() - ? detail_expected::invoke(std::forward(f), *std::forward(exp)) - : Ret(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval()))> -constexpr auto and_then_impl(Exp &&exp, F &&f) { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - - return exp.has_value() ? detail_expected::invoke(std::forward(f)) - : Ret(unexpect, std::forward(exp).error()); -} -#else -template struct TC; -template (), - *std::declval())), - detail_expected::enable_if_t>::value> * = nullptr> -auto and_then_impl(Exp &&exp, F &&f) -> Ret { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - - return exp.has_value() - ? detail_expected::invoke(std::forward(f), *std::forward(exp)) - : Ret(unexpect, std::forward(exp).error()); -} - -template ())), - detail_expected::enable_if_t>::value> * = nullptr> -constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - - return exp.has_value() ? detail_expected::invoke(std::forward(f)) - : Ret(unexpect, std::forward(exp).error()); -} -#endif - -#ifdef WPI_EXPECTED_CXX14 -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - *std::declval())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto expected_map_impl(Exp &&exp, F &&f) { - using result = ret_t>; - return exp.has_value() ? result(detail_expected::invoke(std::forward(f), - *std::forward(exp))) - : result(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - *std::declval())), - detail_expected::enable_if_t::value> * = nullptr> -auto expected_map_impl(Exp &&exp, F &&f) { - using result = expected>; - if (exp.has_value()) { - detail_expected::invoke(std::forward(f), *std::forward(exp)); - return result(); - } - - return result(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto expected_map_impl(Exp &&exp, F &&f) { - using result = ret_t>; - return exp.has_value() ? result(detail_expected::invoke(std::forward(f))) - : result(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval())), - detail_expected::enable_if_t::value> * = nullptr> -auto expected_map_impl(Exp &&exp, F &&f) { - using result = expected>; - if (exp.has_value()) { - detail_expected::invoke(std::forward(f)); - return result(); - } - - return result(unexpect, std::forward(exp).error()); -} -#else -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - *std::declval())), - detail_expected::enable_if_t::value> * = nullptr> - -constexpr auto expected_map_impl(Exp &&exp, F &&f) - -> ret_t> { - using result = ret_t>; - - return exp.has_value() ? result(detail_expected::invoke(std::forward(f), - *std::forward(exp))) - : result(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - *std::declval())), - detail_expected::enable_if_t::value> * = nullptr> - -auto expected_map_impl(Exp &&exp, F &&f) -> expected> { - if (exp.has_value()) { - detail_expected::invoke(std::forward(f), *std::forward(exp)); - return {}; - } - - return unexpected>(std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval())), - detail_expected::enable_if_t::value> * = nullptr> - -constexpr auto expected_map_impl(Exp &&exp, F &&f) - -> ret_t> { - using result = ret_t>; - - return exp.has_value() ? result(detail_expected::invoke(std::forward(f))) - : result(unexpect, std::forward(exp).error()); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval())), - detail_expected::enable_if_t::value> * = nullptr> - -auto expected_map_impl(Exp &&exp, F &&f) -> expected> { - if (exp.has_value()) { - detail_expected::invoke(std::forward(f)); - return {}; - } - - return unexpected>(std::forward(exp).error()); -} -#endif - -#if defined(WPI_EXPECTED_CXX14) && !defined(WPI_EXPECTED_GCC49) && \ - !defined(WPI_EXPECTED_GCC54) && !defined(WPI_EXPECTED_GCC55) -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto map_error_impl(Exp &&exp, F &&f) { - using result = expected, detail_expected::decay_t>; - return exp.has_value() - ? result(*std::forward(exp)) - : result(unexpect, detail_expected::invoke(std::forward(f), - std::forward(exp).error())); -} -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -auto map_error_impl(Exp &&exp, F &&f) { - using result = expected, monostate>; - if (exp.has_value()) { - return result(*std::forward(exp)); - } - - detail_expected::invoke(std::forward(f), std::forward(exp).error()); - return result(unexpect, monostate{}); -} -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto map_error_impl(Exp &&exp, F &&f) { - using result = expected, detail_expected::decay_t>; - return exp.has_value() - ? result() - : result(unexpect, detail_expected::invoke(std::forward(f), - std::forward(exp).error())); -} -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -auto map_error_impl(Exp &&exp, F &&f) { - using result = expected, monostate>; - if (exp.has_value()) { - return result(); - } - - detail_expected::invoke(std::forward(f), std::forward(exp).error()); - return result(unexpect, monostate{}); -} -#else -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto map_error_impl(Exp &&exp, F &&f) - -> expected, detail_expected::decay_t> { - using result = expected, detail_expected::decay_t>; - - return exp.has_value() - ? result(*std::forward(exp)) - : result(unexpect, detail_expected::invoke(std::forward(f), - std::forward(exp).error())); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -auto map_error_impl(Exp &&exp, F &&f) -> expected, monostate> { - using result = expected, monostate>; - if (exp.has_value()) { - return result(*std::forward(exp)); - } - - detail_expected::invoke(std::forward(f), std::forward(exp).error()); - return result(unexpect, monostate{}); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto map_error_impl(Exp &&exp, F &&f) - -> expected, detail_expected::decay_t> { - using result = expected, detail_expected::decay_t>; - - return exp.has_value() - ? result() - : result(unexpect, detail_expected::invoke(std::forward(f), - std::forward(exp).error())); -} - -template >::value> * = nullptr, - class Ret = decltype(detail_expected::invoke(std::declval(), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -auto map_error_impl(Exp &&exp, F &&f) -> expected, monostate> { - using result = expected, monostate>; - if (exp.has_value()) { - return result(); - } - - detail_expected::invoke(std::forward(f), std::forward(exp).error()); - return result(unexpect, monostate{}); -} -#endif - -#ifdef WPI_EXPECTED_CXX14 -template (), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -constexpr auto or_else_impl(Exp &&exp, F &&f) { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - return exp.has_value() ? std::forward(exp) - : detail_expected::invoke(std::forward(f), - std::forward(exp).error()); -} - -template (), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -detail_expected::decay_t or_else_impl(Exp &&exp, F &&f) { - return exp.has_value() ? std::forward(exp) - : (detail_expected::invoke(std::forward(f), - std::forward(exp).error()), - std::forward(exp)); -} -#else -template (), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -auto or_else_impl(Exp &&exp, F &&f) -> Ret { - static_assert(detail_expected::is_expected::value, "F must return an expected"); - return exp.has_value() ? std::forward(exp) - : detail_expected::invoke(std::forward(f), - std::forward(exp).error()); -} - -template (), - std::declval().error())), - detail_expected::enable_if_t::value> * = nullptr> -detail_expected::decay_t or_else_impl(Exp &&exp, F &&f) { - return exp.has_value() ? std::forward(exp) - : (detail_expected::invoke(std::forward(f), - std::forward(exp).error()), - std::forward(exp)); -} -#endif -} // namespace detail_expected - -template -constexpr bool operator==(const expected &lhs, - const expected &rhs) { - return (lhs.has_value() != rhs.has_value()) - ? false - : (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs); -} -template -constexpr bool operator!=(const expected &lhs, - const expected &rhs) { - return (lhs.has_value() != rhs.has_value()) - ? true - : (!lhs.has_value() ? lhs.error() != rhs.error() : *lhs != *rhs); -} -template -constexpr bool operator==(const expected &lhs, - const expected &rhs) { - return (lhs.has_value() != rhs.has_value()) - ? false - : (!lhs.has_value() ? lhs.error() == rhs.error() : true); -} -template -constexpr bool operator!=(const expected &lhs, - const expected &rhs) { - return (lhs.has_value() != rhs.has_value()) - ? true - : (!lhs.has_value() ? lhs.error() == rhs.error() : false); -} - -template -constexpr bool operator==(const expected &x, const U &v) { - return x.has_value() ? *x == v : false; -} -template -constexpr bool operator==(const U &v, const expected &x) { - return x.has_value() ? *x == v : false; -} -template -constexpr bool operator!=(const expected &x, const U &v) { - return x.has_value() ? *x != v : true; -} -template -constexpr bool operator!=(const U &v, const expected &x) { - return x.has_value() ? *x != v : true; -} - -template -constexpr bool operator==(const expected &x, const unexpected &e) { - return x.has_value() ? false : x.error() == e.value(); -} -template -constexpr bool operator==(const unexpected &e, const expected &x) { - return x.has_value() ? false : x.error() == e.value(); -} -template -constexpr bool operator!=(const expected &x, const unexpected &e) { - return x.has_value() ? true : x.error() != e.value(); -} -template -constexpr bool operator!=(const unexpected &e, const expected &x) { - return x.has_value() ? true : x.error() != e.value(); -} - -template ::value || - std::is_move_constructible::value) && - detail_expected::is_swappable::value && - std::is_move_constructible::value && - detail_expected::is_swappable::value> * = nullptr> -void swap(expected &lhs, - expected &rhs) noexcept(noexcept(lhs.swap(rhs))) { - lhs.swap(rhs); -} -} // namespace wpi::util - -#endif diff --git a/wpiutil/src/main/native/thirdparty/json/include/wpi/util/json.hpp b/wpiutil/src/main/native/thirdparty/json/include/wpi/util/json.hpp index 2746badf92..cd9c52ba85 100644 --- a/wpiutil/src/main/native/thirdparty/json/include/wpi/util/json.hpp +++ b/wpiutil/src/main/native/thirdparty/json/include/wpi/util/json.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include "wpi/util/StringMap.hpp" -#include "wpi/util/expected" namespace wpi::util { @@ -153,7 +153,7 @@ class json }; public: - static wpi::util::expected parse(std::string_view); + static std::expected parse(std::string_view); static json parse_or_throw(std::string_view); json(const json&); diff --git a/wpiutil/src/main/native/thirdparty/json/src/json.cpp b/wpiutil/src/main/native/thirdparty/json/src/json.cpp index 7f23ece0e8..c2a897f2ff 100644 --- a/wpiutil/src/main/native/thirdparty/json/src/json.cpp +++ b/wpiutil/src/main/native/thirdparty/json/src/json.cpp @@ -1435,7 +1435,7 @@ json::parse(json& j, const char*& p, const char* e, int context, int depth) return unexpected_eof; } -wpi::util::expected +std::expected json::parse(std::string_view s) { const char* p = s.data(); @@ -1443,12 +1443,12 @@ json::parse(std::string_view s) json j; Status result = parse(j, p, e, 0, DEPTH); if (result != success) { - return wpi::util::unexpected(StatusToString(result)); + return std::unexpected(StatusToString(result)); } json j2; Status s2 = parse(j2, p, e, 0, DEPTH); if (s2 != absent_value) { - return wpi::util::unexpected(StatusToString(trailing_content)); + return std::unexpected(StatusToString(trailing_content)); } return j; } diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/MemoryBuffer.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/MemoryBuffer.cpp index 330f12a014..82627db8eb 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/MemoryBuffer.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/MemoryBuffer.cpp @@ -259,12 +259,12 @@ static std::unique_ptr GetMemoryBufferForStream( return GetMemBufferCopyImpl(buffer, bufferName, ec); } -wpi::util::expected, std::error_code> +std::expected, std::error_code> MemoryBuffer::GetFile(std::string_view filename, int64_t fileSize) { std::error_code ec; auto ret = GetFileAux(filename, ec, fileSize, fileSize, 0); if (ec) { - return wpi::util::unexpected{ec}; + return std::unexpected{ec}; } return ret; } diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemoryBuffer.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemoryBuffer.hpp index ec879782db..de361af43e 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemoryBuffer.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemoryBuffer.hpp @@ -24,7 +24,7 @@ #include #include #include -#include "wpi/util/expected" +#include // Duplicated from fs.h to avoid a dependency namespace fs { @@ -78,7 +78,7 @@ class MemoryBuffer { /// if successful, otherwise returning null. If FileSize is specified, this /// means that the client knows that the file exists and that it has the /// specified size. - static wpi::util::expected, std::error_code> + static std::expected, std::error_code> GetFile(std::string_view filename, int64_t fileSize = -1); /// Read all of the specified file into a MemoryBuffer as a stream diff --git a/wpiutil/src/test/native/cpp/expected/ExpectedTest.cpp b/wpiutil/src/test/native/cpp/expected/ExpectedTest.cpp deleted file mode 100644 index ef7e2475a5..0000000000 --- a/wpiutil/src/test/native/cpp/expected/ExpectedTest.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#include "wpi/util/expected" - -#include -#include -#include -#include - -#include - -namespace { -struct TakesInitAndVariadic { - std::vector v; - std::tuple t; - - template - TakesInitAndVariadic(std::initializer_list l, // NOLINT - Args&&... args) - : v(l), t(std::forward(args)...) {} -}; -} // namespace - -TEST(ExpectedTest, Emplace) { - { - wpi::util::expected, int> e; - e.emplace(new int{42}); - EXPECT_TRUE(e); - EXPECT_EQ(**e, 42); - } - - { - wpi::util::expected, int> e; - e.emplace({0, 1}); - EXPECT_TRUE(e); - EXPECT_EQ((*e)[0], 0); - EXPECT_EQ((*e)[1], 1); - } - - { - wpi::util::expected, int> e; - e.emplace(2, 3); - EXPECT_TRUE(e); - EXPECT_EQ(std::get<0>(*e), 2); - EXPECT_EQ(std::get<1>(*e), 3); - } - - { - wpi::util::expected e = - wpi::util::make_unexpected(0); - e.emplace({0, 1}, 2, 3); - EXPECT_TRUE(e); - EXPECT_EQ(e->v[0], 0); - EXPECT_EQ(e->v[1], 1); - EXPECT_EQ(std::get<0>(e->t), 2); - EXPECT_EQ(std::get<1>(e->t), 3); - } -}