From e33cfdd668366006646259e91ef7c6e9a8ae7cd7 Mon Sep 17 00:00:00 2001 From: Bowen Fu Date: Fri, 24 Jun 2022 08:19:57 +0800 Subject: [PATCH] Fix Id. (#12) Fix id Co-authored-by: Bowen Fu --- .github/workflows/cmake.yml | 2 +- CMakeLists.txt | 2 +- include/hspp.h | 37 ++++++++++++++++++++++++++----------- test/hspp/test.cpp | 24 ++++++++---------------- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index be7a3a0..390ef14 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -39,5 +39,5 @@ jobs: working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest --output-on-failure --parallel 4 -C ${{env.BUILD_TYPE}} + run: ctest --output-on-failure --parallel -C ${{env.BUILD_TYPE}} diff --git a/CMakeLists.txt b/CMakeLists.txt index ac1b764..f1fd581 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ message(STATUS "CXX_STANDARD: ${CMAKE_CXX_STANDARD}") list(APPEND BASE_COMPILE_FLAGS "$<$,$,$>:-Wall;-Wextra;-pedantic;-Werror;-Wno-parentheses;-Wno-shadow;-Wconversion;-Wsign-conversion>" - "$<$:/W4>") # /WX for -Werror + "$<$:/W4;/Zm20>") # /WX for -Werror set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) diff --git a/include/hspp.h b/include/hspp.h index ee7894a..b000575 100644 --- a/include/hspp.h +++ b/include/hspp.h @@ -44,24 +44,37 @@ auto overload(Ts&&... ts) namespace doN { +// make sure Id is not a const obj. template class Id { - // should be std::shared_ptr> - std::shared_ptr mT = std::make_shared(); + using OptT = std::optional; + std::shared_ptr mT = std::make_shared(); public: constexpr Id() = default; constexpr auto const& value() const { if (!mT) + { + throw std::runtime_error{"Invalid id!"}; + } + if (!mT->has_value()) { throw std::runtime_error{"Id has no binding!"}; } - return *mT; + return mT->value(); } - constexpr void bind(T v) + constexpr void bind(T v) const { - *mT = std::move(v); + // if (mT->has_value()) + // { + // throw std::runtime_error{"Id already has a binding!"}; + // } + const_cast(*mT) = std::move(v); + } + constexpr void reset() const + { + const_cast(*mT) = OptT{}; } }; @@ -3251,7 +3264,7 @@ class Traversable : public TraversableBase> - 1; auto last = std::get(in); - auto const func = toGFunc<1>([in=std::move(in)](auto&& lastElem) + auto const func = toGFunc<1>([in=std::forward(in)](auto&& lastElem) { constexpr auto sizeMinusOne = std::tuple_size_v> - 1; return std::tuple_cat(subtuple<0, sizeMinusOne>(std::move(in)), std::make_tuple(lastElem)); @@ -3417,14 +3430,14 @@ class DeMonad { return mM; } - constexpr auto id() const -> std::reference_wrapper> + constexpr auto id() const -> Id { return mId; } private: std::reference_wrapper mM; - std::reference_wrapper> mId; + Id mId; }; template @@ -3508,13 +3521,15 @@ BIN_OP_FOR_NULLARY(<) BIN_OP_FOR_NULLARY(&&) template -constexpr auto funcWithParams(std::reference_wrapper> const& param, BodyBaker const& bodyBaker) +constexpr auto funcWithParams(Id const& param, BodyBaker const& bodyBaker) { return [=](T const& t) { // bind before baking body. - param.get().bind(t); - return evaluate_(bodyBaker()); + const_cast&>(param).bind(t); + auto result = evaluate_(bodyBaker()); + // const_cast&>(param).reset(); + return result; }; } diff --git a/test/hspp/test.cpp b/test/hspp/test.cpp index 4863006..48b9fa1 100644 --- a/test/hspp/test.cpp +++ b/test/hspp/test.cpp @@ -1421,24 +1421,16 @@ constexpr auto isSpace = toFunc<> | [](char c) const auto space = many || sat | isSpace; -// // This will fail some tests. -// constexpr auto token = toGFunc<1> | [](auto p) -// { -// using A = DataType; -// doN::Id a; -// return doN::do_( -// a <= p, -// space, -// return_ | a -// ); -// }; - +// This will fail some tests. constexpr auto token = toGFunc<1> | [](auto p) { - return p >>= [](auto a) { return - space >> - (return_ | a); - }; + using A = DataType>; + doN::Id a; + return doN::do_( + a <= p, + space, + return_ | a + ); }; constexpr auto symb = token string;