From f654228feab91b089b5f90763cb90db3ef67ae19 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Tue, 5 Nov 2024 07:53:28 -0800 Subject: [PATCH 01/15] build: wiping out defunct and broken test --- test/rtos/esp8266/collection/Makefile | 10 ---------- test/rtos/esp8266/collection/components | 1 - test/rtos/esp8266/collection/main/component.mk | 0 test/rtos/esp8266/collection/main/components.cpp | 1 - test/rtos/esp8266/collection/main/user_main.c | 1 - test/rtos/esp8266/collection/version_finder.mk | 1 - 6 files changed, 14 deletions(-) delete mode 100644 test/rtos/esp8266/collection/Makefile delete mode 120000 test/rtos/esp8266/collection/components delete mode 100644 test/rtos/esp8266/collection/main/component.mk delete mode 120000 test/rtos/esp8266/collection/main/components.cpp delete mode 120000 test/rtos/esp8266/collection/main/user_main.c delete mode 120000 test/rtos/esp8266/collection/version_finder.mk diff --git a/test/rtos/esp8266/collection/Makefile b/test/rtos/esp8266/collection/Makefile deleted file mode 100644 index 7cf18150..00000000 --- a/test/rtos/esp8266/collection/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# This is a project Makefile. It is assumed the directory this Makefile resides in is a -# project subdirectory. -# - -PROJECT_NAME := collection - -include version_finder.mk - -include $(IDF_PATH)/make/project.mk diff --git a/test/rtos/esp8266/collection/components b/test/rtos/esp8266/collection/components deleted file mode 120000 index 192059cd..00000000 --- a/test/rtos/esp8266/collection/components +++ /dev/null @@ -1 +0,0 @@ -../template/components \ No newline at end of file diff --git a/test/rtos/esp8266/collection/main/component.mk b/test/rtos/esp8266/collection/main/component.mk deleted file mode 100644 index e69de29b..00000000 diff --git a/test/rtos/esp8266/collection/main/components.cpp b/test/rtos/esp8266/collection/main/components.cpp deleted file mode 120000 index 7fecdcef..00000000 --- a/test/rtos/esp8266/collection/main/components.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../esp32/collection/main/components.cpp \ No newline at end of file diff --git a/test/rtos/esp8266/collection/main/user_main.c b/test/rtos/esp8266/collection/main/user_main.c deleted file mode 120000 index 0ee68348..00000000 --- a/test/rtos/esp8266/collection/main/user_main.c +++ /dev/null @@ -1 +0,0 @@ -../../template/user_main.c \ No newline at end of file diff --git a/test/rtos/esp8266/collection/version_finder.mk b/test/rtos/esp8266/collection/version_finder.mk deleted file mode 120000 index 65e73b66..00000000 --- a/test/rtos/esp8266/collection/version_finder.mk +++ /dev/null @@ -1 +0,0 @@ -../template/version_finder.mk \ No newline at end of file From b2efc08f3349efbf56a2aba89b20168f38ab44e0 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Tue, 5 Nov 2024 08:00:18 -0800 Subject: [PATCH 02/15] refactor: phasing out "estdlib" in favor of "estd" --- NOTICE | 4 ++-- test/rtos/esp32/chrono/CMakeLists.txt | 4 ++-- test/rtos/esp32/setenv.cmake | 8 ++++---- tools/esp-idf/components/estdlib/CMakeLists.txt | 8 -------- tools/esp-idf/components/estdlib/idf_component.yml | 1 - 5 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 tools/esp-idf/components/estdlib/CMakeLists.txt delete mode 120000 tools/esp-idf/components/estdlib/idf_component.yml diff --git a/NOTICE b/NOTICE index 39015b65..ab4604a1 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,2 @@ -Embedded std library (estdlib) -Copyright 2023 Malachi Burke +Embedded std library (estd) +Copyright 2023, 2024 Malachi Burke diff --git a/test/rtos/esp32/chrono/CMakeLists.txt b/test/rtos/esp32/chrono/CMakeLists.txt index e3565105..9c130959 100644 --- a/test/rtos/esp32/chrono/CMakeLists.txt +++ b/test/rtos/esp32/chrono/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.5) -set(ESTDLIB_DIR ../../../..) +set(ROOT_DIR ../../../..) -include(${ESTDLIB_DIR}/tools/esp-idf/project.cmake) +include(${ROOT_DIR}/tools/esp-idf/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(chrono) \ No newline at end of file diff --git a/test/rtos/esp32/setenv.cmake b/test/rtos/esp32/setenv.cmake index d92ee4b7..90142d5f 100644 --- a/test/rtos/esp32/setenv.cmake +++ b/test/rtos/esp32/setenv.cmake @@ -1,13 +1,13 @@ -set(ESTDLIB_DIR ../../../..) +set(ROOT_DIR ../../../..) #set(ESTDLIB_DIR "dummy") # DEBT: 23JUL23 Fixed this line but haven't tested yet get_filename_component(ESTDLIB_DIR - "${CMAKE_CURRENT_LIST_DIR}/${ESTDLIB_DIR}" + "${CMAKE_CURRENT_LIST_DIR}/${ROOT_DIR}" ABSOLUTE) -#message("ESTDLIB building: ${ESTDLIB_DIR}") +#message("ESTDLIB building: ${ROOT_DIR}") -include(${ESTDLIB_DIR}/tools/esp-idf/project.cmake) +include(${ROOT_DIR}/tools/esp-idf/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/tools/esp-idf/components/estdlib/CMakeLists.txt b/tools/esp-idf/components/estdlib/CMakeLists.txt deleted file mode 100644 index dd50a008..00000000 --- a/tools/esp-idf/components/estdlib/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -if(NOT DEFINED CMAKE_BUILD_EARLY_EXPANSION) - # 25SEP24 MB DEBT - # Due to my ancient test project structure, it's hard to tell if this - # is working quite right. Seems to fire too often. - message(WARNING "estdlib target is deprecated. Use estd instead") -endif() - -include(${CMAKE_CURRENT_LIST_DIR}/../../component.cmake NO_POLICY_SCOPE) diff --git a/tools/esp-idf/components/estdlib/idf_component.yml b/tools/esp-idf/components/estdlib/idf_component.yml deleted file mode 120000 index f0c59710..00000000 --- a/tools/esp-idf/components/estdlib/idf_component.yml +++ /dev/null @@ -1 +0,0 @@ -../estd/idf_component.yml \ No newline at end of file From f6f9a758397e46848cfa5aad3ff8a1628906545b Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Tue, 5 Nov 2024 08:04:20 -0800 Subject: [PATCH 03/15] fix: repairing namespace compilation error --- src/estd/istream.h | 3 ++- test/unity/streambuf.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/estd/istream.h b/src/estd/istream.h index 0c632e4f..007f6135 100644 --- a/src/estd/istream.h +++ b/src/estd/istream.h @@ -166,7 +166,8 @@ detail::basic_istream& operator >>( return in; } - +// 05NOV24 MB - perhaps these would more comfortably +// live in estd itself rather than estd::detail namespace detail { template > diff --git a/test/unity/streambuf.cpp b/test/unity/streambuf.cpp index 2a5b19ce..a74d69e6 100644 --- a/test/unity/streambuf.cpp +++ b/test/unity/streambuf.cpp @@ -18,7 +18,7 @@ static void test_ospanbuf() char buf[128]; estd::span span(buf); - estd::experimental::ospanbuf os(span); + estd::detail::ospanbuf os(span); os.sputc('a'); os.sputn(" test 567", 9); @@ -36,7 +36,7 @@ static void test_ispanbuf() char buf[] = "hi2u 1234"; estd::span span(buf); - estd::experimental::ispanbuf os(span); + estd::detail::ispanbuf os(span); char c = os.sbumpc(); @@ -66,7 +66,7 @@ static void test_ospanstream() char buf[128]; estd::span span(buf); - estd::experimental::ospanstream os(span); + estd::detail::ospanstream os(span); os << "hi2u"; @@ -85,7 +85,7 @@ static void test_ispanstream() // DEBT: make const char span operable estd::span span(buf); - estd::experimental::ispanstream is(span); + estd::detail::ispanstream is(span); estd::layer1::string<64> s; From 5a45c589ecf657a905ce208c59412c2eb5d5ecb6 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Sat, 16 Nov 2024 22:45:56 -0800 Subject: [PATCH 04/15] fix(tuple): tuple.visit now plays nice with references --- CHANGELOG.md | 6 ++++++ src/estd/internal/macro/cpp.h | 2 +- src/estd/internal/raw/utility.h | 8 +++++--- src/estd/internal/variadic/visitor.h | 6 +++++- test/catch/CMakeLists.txt | 1 + test/catch/tuple-test.cpp | 8 ++++++++ 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1320ec62..498ef85a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v0.?.? - DDMMM24 + +## Quality Updates & Bug Fixes + +* https://github.com/malachi-iot/estdlib/issues/66 `tuple.visit()` now works with references too + # v0.8.1 - 31OCT24 ## Added Features diff --git a/src/estd/internal/macro/cpp.h b/src/estd/internal/macro/cpp.h index 6e90d4ae..c8021732 100644 --- a/src/estd/internal/macro/cpp.h +++ b/src/estd/internal/macro/cpp.h @@ -9,7 +9,7 @@ // Assistance to define typical "typedef T value_type" and friends #define ESTD_CPP_STD_VALUE_TYPE(T) \ -typedef T value_type; \ + typedef T value_type; \ typedef value_type& reference; \ typedef const value_type& const_reference; \ typedef value_type* pointer; \ diff --git a/src/estd/internal/raw/utility.h b/src/estd/internal/raw/utility.h index abcaba1d..73c55f85 100644 --- a/src/estd/internal/raw/utility.h +++ b/src/estd/internal/raw/utility.h @@ -15,17 +15,19 @@ struct in_place_conditional_t : in_place_tag {}; struct in_place_t : internal::in_place_tag { - + explicit in_place_t() = default; }; template struct in_place_type_t : internal::in_place_tag { - + explicit in_place_type_t() = default; }; template struct in_place_index_t : internal::in_place_tag -{}; +{ + explicit in_place_index_t() = default; +}; } diff --git a/src/estd/internal/variadic/visitor.h b/src/estd/internal/variadic/visitor.h index 30505a13..9075bee7 100644 --- a/src/estd/internal/variadic/visitor.h +++ b/src/estd/internal/variadic/visitor.h @@ -60,7 +60,11 @@ struct visitor_index : in_place_index_t template struct visitor_instance : in_place_type_t { - ESTD_CPP_STD_VALUE_TYPE(T) + using value_type = estd::remove_reference_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; reference value; diff --git a/test/catch/CMakeLists.txt b/test/catch/CMakeLists.txt index 3b0f2e73..942f55ac 100644 --- a/test/catch/CMakeLists.txt +++ b/test/catch/CMakeLists.txt @@ -37,6 +37,7 @@ add_subdirectory(${ROOT_DIR} estd) set(EXTRA_FILES ${ROOT_DIR}/README.md + ${ROOT_DIR}/CHANGELOG.md ${ROOT_DIR}/docs/Variadic.md ${ROOT_DIR}/docs/Units.md ) diff --git a/test/catch/tuple-test.cpp b/test/catch/tuple-test.cpp index d77e73a9..86acc5ff 100644 --- a/test/catch/tuple-test.cpp +++ b/test/catch/tuple-test.cpp @@ -174,6 +174,14 @@ TEST_CASE("tuple") int_ref = 5; REQUIRE(int_value == 5); + + tuple3.visit([](estd::variadic::v2::instance<0, int&> i) + { + i.value = 10; + return false; + }); + + REQUIRE(int_value == 10); } SECTION("multiple identical") { From 18a9d98c41df6906832333d723f04399b38de5db Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 22 Nov 2024 07:08:40 -0800 Subject: [PATCH 05/15] fix: repairing regression from "in_place_type_t" modification --- src/estd/internal/raw/utility.h | 6 ++-- src/estd/internal/tuple.h | 1 - src/estd/internal/variadic/visitor.h | 44 +++++++++++++++------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/estd/internal/raw/utility.h b/src/estd/internal/raw/utility.h index 73c55f85..0a32ba54 100644 --- a/src/estd/internal/raw/utility.h +++ b/src/estd/internal/raw/utility.h @@ -15,19 +15,19 @@ struct in_place_conditional_t : in_place_tag {}; struct in_place_t : internal::in_place_tag { - explicit in_place_t() = default; + constexpr explicit in_place_t() = default; }; template struct in_place_type_t : internal::in_place_tag { - explicit in_place_type_t() = default; + constexpr explicit in_place_type_t() = default; }; template struct in_place_index_t : internal::in_place_tag { - explicit in_place_index_t() = default; + constexpr explicit in_place_index_t() = default; }; } diff --git a/src/estd/internal/tuple.h b/src/estd/internal/tuple.h index 93d8d950..49502e7a 100644 --- a/src/estd/internal/tuple.h +++ b/src/estd/internal/tuple.h @@ -8,7 +8,6 @@ #include "tuple/get.h" // DEBT: Must precede 'visitor.h' likely due to probable lack of 'get' forward declaration #include "tuple/sparse.h" -// EXPERIMENTAL #include "variadic/visitor.h" namespace estd { namespace internal { diff --git a/src/estd/internal/variadic/visitor.h b/src/estd/internal/variadic/visitor.h index 9075bee7..11f6067d 100644 --- a/src/estd/internal/variadic/visitor.h +++ b/src/estd/internal/variadic/visitor.h @@ -181,6 +181,8 @@ struct visitor_index : in_place_type_t, type_identity { + // Needed to soften 'explicit' in_place_type_t + constexpr visitor_index() = default; }; template @@ -220,23 +222,23 @@ struct visitor_instance : internal::visitor_instanc namespace concepts { -template -concept GetterFunctor = requires(T f, TProvider& provider) +template +concept GetterFunctor = requires(T f, Provider& provider) { f(visitor_index<0, int>{}, provider); }; -template -concept ClassVisitorFunctor = requires(T f, TArgs&&...args) +template +concept ClassVisitorFunctor = requires(T f, Args&&...args) { - { f(visitor_index<0, int>{}, std::forward(args)...) } -> std::same_as; + { f(visitor_index<0, int>{}, std::forward(args)...) } -> std::same_as; }; -template -concept InstanceVisitorFunctor = requires(T f, TArgs&&...args, int v) +template +concept InstanceVisitorFunctor = requires(T f, Args&&...args, int v) { - { f(visitor_instance<0, int>(v), std::forward(args)...) } -> std::same_as; + { f(visitor_instance<0, int>(v), std::forward(args)...) } -> std::same_as; }; } @@ -254,18 +256,18 @@ struct value_visitor template , - class... TArgs, + class... Args, class F> - static constexpr short visit(F&&, TArgs&&...) { return -1; } + static constexpr short visit(F&&, Args&&...) { return -1; } template , - class... TArgs> - constexpr static int visit(F&& f, TArgs&&...args) + class... Args> + constexpr static int visit(F&& f, Args&&...args) { - return f(value{}, std::forward(args)...) ? + return f(value{}, std::forward(args)...) ? I : - visit(std::forward(f), std::forward(args)...); + visit(std::forward(f), std::forward(args)...); } }; @@ -278,23 +280,23 @@ struct type_visitor template , - class... TArgs, + class... Args, #if __cpp_concepts - concepts::ClassVisitorFunctor F> + concepts::ClassVisitorFunctor F> #else class F> #endif - static constexpr short visit(F&&, TArgs&&...) { return -1; } + static constexpr short visit(F&&, Args&&...) { return -1; } template , - class... TArgs> - static int visit(F&& f, TArgs&&...args) + class... Args> + static int visit(F&& f, Args&&...args) { - if(f(visitor_index>{}, std::forward(args)...)) + if(f(visitor_index>{}, std::forward(args)...)) return I; - return visit(std::forward(f), std::forward(args)...); + return visit(std::forward(f), std::forward(args)...); } template Date: Fri, 22 Nov 2024 07:29:30 -0800 Subject: [PATCH 06/15] feat: "blessing" copy_n https://github.com/malachi-iot/estdlib/issues/67 --- src/estd/algorithm.h | 32 +++++++++++++--------------- src/estd/internal/macro/c++11_emul.h | 23 ++++++++++++++++++++ src/estd/internal/raw/type_traits.h | 2 +- test/catch/ios-test.cpp | 2 +- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/estd/algorithm.h b/src/estd/algorithm.h index 45e465b0..70378983 100644 --- a/src/estd/algorithm.h +++ b/src/estd/algorithm.h @@ -23,7 +23,7 @@ namespace estd { // Shamelessly lifted from https://en.cppreference.com/w/cpp/algorithm/fill_n template -inline OutputIt fill_n(OutputIt first, Size count, const T& value) +ESTD_CPP_CONSTEXPR(20) OutputIt fill_n(OutputIt first, Size count, const T& value) { #if FEATURE_ESTD_ALGORITHM_OPT return std::fill_n(first, count, value); @@ -89,7 +89,7 @@ ForwardIt min_element(ForwardIt first, ForwardIt last, #endif template -inline OutputIt copy(InputIt first, InputIt last, +ESTD_CPP_CONSTEXPR(20) OutputIt copy(InputIt first, InputIt last, OutputIt d_first) { #if FEATURE_ESTD_ALGORITHM_OPT @@ -106,12 +106,16 @@ inline OutputIt copy(InputIt first, InputIt last, // has a more complex implementation, but unsure why. Maybe they want to avoid incrementing the source // iterator unnecessarily? template -inline OutputIt copy_n(InputIt first, Size count, OutputIt result) +ESTD_CPP_CONSTEXPR(20) OutputIt copy_n(InputIt first, Size count, OutputIt result) { +#if FEATURE_ESTD_ALGORITHM_OPT + return std::copy_n(first, count, result); +#else while(count--) *result++ = *first++; return result; +#endif } @@ -160,26 +164,20 @@ InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) return last; } -template -#ifdef FEATURE_CPP_CONSTEXPR_METHOD -constexpr -#endif -const T& clamp( const T& v, const T& lo, const T& hi ) -{ - return clamp( v, lo, hi, estd::less() ); -} - - template -#if defined(FEATURE_CPP_CONSTEXPR_METHOD) && !defined(ESP8266) -constexpr -#endif -const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ) +ESTD_CPP_CONSTEXPR(17) const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ) { return assert( !comp(hi, lo) ), comp(v, lo) ? lo : comp(hi, v) ? hi : v; } +template +ESTD_CPP_CONSTEXPR(17) const T& clamp( const T& v, const T& lo, const T& hi ) +{ + return estd::clamp( v, lo, hi, estd::less() ); +} + + // UNTESTED template #ifdef FEATURE_CPP_CONSTEXPR_METHOD diff --git a/src/estd/internal/macro/c++11_emul.h b/src/estd/internal/macro/c++11_emul.h index b81caa11..5dc1edb7 100644 --- a/src/estd/internal/macro/c++11_emul.h +++ b/src/estd/internal/macro/c++11_emul.h @@ -32,6 +32,29 @@ #define ESTD_CPP_CONSTEXPR_RET inline #endif +// Take pages out of GCC playbook +// DEBT: These belong elsewhere, not in c++_emul per se +#if __cplusplus >= 202002L +#define ESTD_CPP20_CONSTEXPR constexpr +#else +#define ESTD_CPP20_CONSTEXPR +#endif + +#if __cplusplus >= 201703L +#define ESTD_CPP17_CONSTEXPR constexpr +#else +#define ESTD_CPP17_CONSTEXPR +#endif + +#if __cplusplus >= 201402L +#define ESTD_CPP14_CONSTEXPR constexpr +#else +#define ESTD_CPP14_CONSTEXPR +#endif + + +#define ESTD_CPP_CONSTEXPR(v) ESTD_CPP ## v ## _CONSTEXPR + #if __cpp_ref_qualifiers #define ESTD_CPP_REFQ & #else diff --git a/src/estd/internal/raw/type_traits.h b/src/estd/internal/raw/type_traits.h index 1ae4d580..3a637ea8 100644 --- a/src/estd/internal/raw/type_traits.h +++ b/src/estd/internal/raw/type_traits.h @@ -24,7 +24,7 @@ struct type_identity { typedef T type; }; template struct integral_constant { - static CONSTEXPR T value = v; + static constexpr T value = v; typedef T value_type; typedef integral_constant type; // using injected-class-name diff --git a/test/catch/ios-test.cpp b/test/catch/ios-test.cpp index 7da51b83..46552a90 100644 --- a/test/catch/ios-test.cpp +++ b/test/catch/ios-test.cpp @@ -130,7 +130,7 @@ typedef internal::streambuf dummy_streambuf; TEST_CASE("ios") { const char raw_str[] = "raw 'traditional' output\n"; - CONSTEXPR int raw_str_len = sizeof(raw_str) - 1; + constexpr int raw_str_len = sizeof(raw_str) - 1; /* This old cute and clever function-detector method no longer employed. * Ended up being more complicated than not using it in the end From 032de79c2453c87e8d260e381d8d2146c1791266 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 22 Nov 2024 07:39:54 -0800 Subject: [PATCH 07/15] fix: repairing regression from "in_place_type_t" modification --- src/estd/internal/variadic/visitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/estd/internal/variadic/visitor.h b/src/estd/internal/variadic/visitor.h index 11f6067d..c24342fc 100644 --- a/src/estd/internal/variadic/visitor.h +++ b/src/estd/internal/variadic/visitor.h @@ -182,7 +182,7 @@ struct visitor_index : type_identity { // Needed to soften 'explicit' in_place_type_t - constexpr visitor_index() = default; + constexpr visitor_index() : in_place_type_t() {} }; template From 62e6e604fd17008fa96f79e90cc1f4ec98e95fe6 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Wed, 27 Nov 2024 09:28:33 -0800 Subject: [PATCH 08/15] feat: adding get(tuple) Mostly works. Still needs compile time enforcement of "exactly one element of that type" https://github.com/malachi-iot/estdlib/issues/69 --- src/estd/internal/tuple/get.h | 30 ++++++++++++++++++++-- src/estd/internal/variadic/type_sequence.h | 17 ++++++++++++ test/catch/tuple-test.cpp | 11 ++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/estd/internal/tuple/get.h b/src/estd/internal/tuple/get.h index 046ce523..4b5d59a5 100644 --- a/src/estd/internal/tuple/get.h +++ b/src/estd/internal/tuple/get.h @@ -1,6 +1,7 @@ #pragma once #include "fwd.h" +#include "../variadic/type_sequence.h" namespace estd { @@ -64,14 +65,14 @@ constexpr typename tuple_element >::const_valref_type get } template -inline typename tuple_element >::valref_type get( +ESTD_CPP_CONSTEXPR(20) typename tuple_element >::valref_type get( internal::tuple& t) { return internal::GetImpl::value(t); } template -inline tuple_element_t >&& get(internal::tuple&& t) +ESTD_CPP_CONSTEXPR(20) tuple_element_t >&& get(internal::tuple&& t) { return internal::GetImpl::value(std::move(t)); } @@ -82,4 +83,29 @@ constexpr tuple_element_t >&& get(const internal::tuple::value(t); } +template +ESTD_CPP_CONSTEXPR(14) T& get(internal::tuple& t) +{ + return get::index>(t); +} + + +template +ESTD_CPP_CONSTEXPR(14) T&& get(internal::tuple&& t) +{ + return get::index>(t); +} + +template +constexpr const T& get(const internal::tuple& t) +{ + return get::index>(t); +} + +template +constexpr const T&& get(const internal::tuple&& t) +{ + return get::index>(t); +} + } diff --git a/src/estd/internal/variadic/type_sequence.h b/src/estd/internal/variadic/type_sequence.h index 86c7599e..a75ec7c9 100644 --- a/src/estd/internal/variadic/type_sequence.h +++ b/src/estd/internal/variadic/type_sequence.h @@ -19,6 +19,23 @@ struct get_type_at_index : }; +template +struct get_index_of_type : get_index_of_type +{ + static constexpr bool matched = false; + //static constexpr unsigned index = sizeof ...(Types); +}; + +template +struct get_index_of_type +{ + //static_assert(get_index_of_type::matched == false, "Only one match allowed"); + + static constexpr bool matched = true; + static constexpr unsigned index = sizeof ...(Types); +}; + + template struct type_sequence_accessor { diff --git a/test/catch/tuple-test.cpp b/test/catch/tuple-test.cpp index 86acc5ff..0331363f 100644 --- a/test/catch/tuple-test.cpp +++ b/test/catch/tuple-test.cpp @@ -161,6 +161,10 @@ TEST_CASE("tuple") double& v2 = get<1>(tuple); REQUIRE(v2 == val2); + + double& v3 = get(tuple); + + REQUIRE(v3 == v2); } WHEN("more reference tests") { @@ -193,6 +197,8 @@ TEST_CASE("tuple") get<0>(tuple3).val1 = 1; get<1>(tuple3).val1 = 2; get<2>(tuple3).val1 = 2; + + //get>(tuple3).val1 = 2; } } SECTION("value initialization") @@ -374,7 +380,7 @@ TEST_CASE("tuple") } SECTION("array ref") { - const char (&s)[4] = "hi!"; + static const char (&s)[4] = "hi!"; const tuple v(s); #if __cplusplus >= 201402L @@ -383,7 +389,8 @@ TEST_CASE("tuple") int which = v.visit([](variadic::v3::instance v) #endif { - REQUIRE(v.value == s); + REQUIRE(v.value[0] == s[0]); + REQUIRE(v.value[2] == s[2]); return true; }); From 1e5dedb43929c057bd11c09577d9b0e278314509 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Wed, 27 Nov 2024 09:40:28 -0800 Subject: [PATCH 09/15] feat: adding get(tuple) Enforcing one and only one rule --- src/estd/internal/variadic/type_sequence.h | 16 ++++++++-------- test/catch/tuple-test.cpp | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/estd/internal/variadic/type_sequence.h b/src/estd/internal/variadic/type_sequence.h index a75ec7c9..7ef872e1 100644 --- a/src/estd/internal/variadic/type_sequence.h +++ b/src/estd/internal/variadic/type_sequence.h @@ -18,20 +18,20 @@ struct get_type_at_index : { }; +// defaults to no match (value == false) +template +struct get_index_of_type : bool_constant { }; +// keeps looking during no match template -struct get_index_of_type : get_index_of_type -{ - static constexpr bool matched = false; - //static constexpr unsigned index = sizeof ...(Types); -}; +struct get_index_of_type : get_index_of_type {}; template -struct get_index_of_type +struct get_index_of_type : bool_constant { - //static_assert(get_index_of_type::matched == false, "Only one match allowed"); + // looks through remaining types to see if others are present + static_assert(get_index_of_type::value == false, "Only one match allowed"); - static constexpr bool matched = true; static constexpr unsigned index = sizeof ...(Types); }; diff --git a/test/catch/tuple-test.cpp b/test/catch/tuple-test.cpp index 0331363f..f719e866 100644 --- a/test/catch/tuple-test.cpp +++ b/test/catch/tuple-test.cpp @@ -198,6 +198,7 @@ TEST_CASE("tuple") get<1>(tuple3).val1 = 2; get<2>(tuple3).val1 = 2; + // properly doesn't compile, as per https://en.cppreference.com/w/cpp/utility/tuple/get //get>(tuple3).val1 = 2; } } From 718b702f0de5bf6f4adb61b17d487852558fca6c Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Wed, 27 Nov 2024 10:05:42 -0800 Subject: [PATCH 10/15] feat: fixing some 'get' glitches, still underway https://github.com/malachi-iot/estdlib/issues/69 --- src/estd/internal/variadic/type_sequence.h | 24 +++++++++++++++++----- test/catch/tuple-test.cpp | 5 +++-- test/catch/variadic-test.cpp | 9 ++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/estd/internal/variadic/type_sequence.h b/src/estd/internal/variadic/type_sequence.h index 7ef872e1..1806ba3c 100644 --- a/src/estd/internal/variadic/type_sequence.h +++ b/src/estd/internal/variadic/type_sequence.h @@ -18,23 +18,37 @@ struct get_type_at_index : { }; -// defaults to no match (value == false) +// DEBT: See if we can consolidate with "get_index_finder" + +// defaults to zero matches (value == 0) template -struct get_index_of_type : bool_constant { }; +struct detail_get_index_of_type : integral_constant { }; // keeps looking during no match template -struct get_index_of_type : get_index_of_type {}; +struct detail_get_index_of_type : detail_get_index_of_type {}; +// increments match counter (++value), finds first occurence of Match but continues +// template -struct get_index_of_type : bool_constant +struct detail_get_index_of_type : + integral_constant::value + 1> { // looks through remaining types to see if others are present - static_assert(get_index_of_type::value == false, "Only one match allowed"); + //static_assert(get_index_of_type::value == false, "Only one match allowed"); static constexpr unsigned index = sizeof ...(Types); }; +template +struct get_index_of_type +{ + using detail = detail_get_index_of_type; + + static constexpr unsigned matches = detail::value; + static constexpr unsigned index = (sizeof...(Types) - 1) - detail::index; +}; + template struct type_sequence_accessor diff --git a/test/catch/tuple-test.cpp b/test/catch/tuple-test.cpp index f719e866..26f9ea89 100644 --- a/test/catch/tuple-test.cpp +++ b/test/catch/tuple-test.cpp @@ -162,9 +162,10 @@ TEST_CASE("tuple") REQUIRE(v2 == val2); - double& v3 = get(tuple); + // FIX: Not quite working + //double& v3 = get(tuple); - REQUIRE(v3 == v2); + //REQUIRE(v3 == v2); } WHEN("more reference tests") { diff --git a/test/catch/variadic-test.cpp b/test/catch/variadic-test.cpp index 0cb8e4db..f1ebdf67 100644 --- a/test/catch/variadic-test.cpp +++ b/test/catch/variadic-test.cpp @@ -578,6 +578,15 @@ TEST_CASE("variadic") REQUIRE(result == 2); } } + SECTION("get_index_of_type") + { + using type1 = internal::get_index_of_type; + int index = type1::index; + + REQUIRE(index == 1); + //static_assert(type1::index == 3, ""); + static_assert(type1::matches == 4, ""); + } } #include "macro/pop.h" From 0cda8061a81d6f54b8c2eab86cf7ce25e81cf175 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Wed, 27 Nov 2024 10:46:01 -0800 Subject: [PATCH 11/15] feat: get(tuple) works https://github.com/malachi-iot/estdlib/issues/69 --- CHANGELOG.md | 6 +++++- src/estd/internal/tuple/get.h | 8 ++++---- src/estd/internal/variadic/type_sequence.h | 13 +++++++------ test/catch/variadic-test.cpp | 11 ++++++++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 498ef85a..71157b1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -# v0.?.? - DDMMM24 +# v0.8.2 - DDMMM24 + +## Added Features + +* https://github.com/malachi-iot/estdlib/issues/69 `get(tuple)` now available ## Quality Updates & Bug Fixes diff --git a/src/estd/internal/tuple/get.h b/src/estd/internal/tuple/get.h index 4b5d59a5..0189bfb6 100644 --- a/src/estd/internal/tuple/get.h +++ b/src/estd/internal/tuple/get.h @@ -86,26 +86,26 @@ constexpr tuple_element_t >&& get(const internal::tuple ESTD_CPP_CONSTEXPR(14) T& get(internal::tuple& t) { - return get::index>(t); + return get::index>(t); } template ESTD_CPP_CONSTEXPR(14) T&& get(internal::tuple&& t) { - return get::index>(t); + return get::index>(t); } template constexpr const T& get(const internal::tuple& t) { - return get::index>(t); + return get::index>(t); } template constexpr const T&& get(const internal::tuple&& t) { - return get::index>(t); + return get::index>(t); } } diff --git a/src/estd/internal/variadic/type_sequence.h b/src/estd/internal/variadic/type_sequence.h index 1806ba3c..9eeb0544 100644 --- a/src/estd/internal/variadic/type_sequence.h +++ b/src/estd/internal/variadic/type_sequence.h @@ -18,7 +18,7 @@ struct get_type_at_index : { }; -// DEBT: See if we can consolidate with "get_index_finder" +// DEBT: Try to consolidate with "get_index_finder" and "selector" // defaults to zero matches (value == 0) template @@ -29,19 +29,15 @@ template struct detail_get_index_of_type : detail_get_index_of_type {}; // increments match counter (++value), finds first occurence of Match but continues -// template struct detail_get_index_of_type : integral_constant::value + 1> { - // looks through remaining types to see if others are present - //static_assert(get_index_of_type::value == false, "Only one match allowed"); - static constexpr unsigned index = sizeof ...(Types); }; template -struct get_index_of_type +struct first_index_of_type { using detail = detail_get_index_of_type; @@ -49,6 +45,11 @@ struct get_index_of_type static constexpr unsigned index = (sizeof...(Types) - 1) - detail::index; }; +template +struct single_index_of_type : first_index_of_type +{ + static_assert(first_index_of_type::matches == 1, "One and only one match is permitted"); +}; template struct type_sequence_accessor diff --git a/test/catch/variadic-test.cpp b/test/catch/variadic-test.cpp index f1ebdf67..98eb805c 100644 --- a/test/catch/variadic-test.cpp +++ b/test/catch/variadic-test.cpp @@ -580,12 +580,21 @@ TEST_CASE("variadic") } SECTION("get_index_of_type") { - using type1 = internal::get_index_of_type; + using type1 = internal::first_index_of_type; + using type2 = internal::first_index_of_type; + using type3 = internal::single_index_of_type; + //using type4 = internal::single_index_of_type; int index = type1::index; REQUIRE(index == 1); //static_assert(type1::index == 3, ""); static_assert(type1::matches == 4, ""); + static_assert(type2::index == 0, ""); + static_assert(type2::matches == 1, ""); + static_assert(type3::index == 3, ""); + static_assert(type3::matches == 1, ""); + // compile-time fails as it should + //static_assert(type4::index == 1, ""); } } From 6c26f493852f36ff6a427b628266fce7a55e95b9 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 6 Dec 2024 17:13:18 -0800 Subject: [PATCH 12/15] build: passing initial testing --- test/catch/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/catch/CMakeLists.txt b/test/catch/CMakeLists.txt index 942f55ac..7e3e26a7 100644 --- a/test/catch/CMakeLists.txt +++ b/test/catch/CMakeLists.txt @@ -133,3 +133,9 @@ endif() # -Wextra) not ready for this just yet, but want it target_link_libraries(${PROJECT_NAME} estd Catch2::Catch2) + +list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/contrib) + +include(CTest) +include(Catch) +catch_discover_tests(${PROJECT_NAME}) From e2f33189d5ac0a87f42406d9082d42f6d765b25e Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 6 Dec 2024 22:58:21 -0800 Subject: [PATCH 13/15] build: bringing in CI yml from exp branch --- .github/workflows/cmake.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 00000000..8de34ca7 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,27 @@ +name: CMake + +on: + push: + branches: [ "dev/**", "alpha" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + env: + unit_test_dir: ${{github.workspace}}/test/catch + + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + uses: threeal/cmake-action@v2.0.0 + with: + source-dir: ${{env.unit_test_dir}} + From be5677d7e1278598334e3663c0532d18ad1ed859 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 6 Dec 2024 23:25:33 -0800 Subject: [PATCH 14/15] build: adding CTest stage to CI, prepping CPM use --- .github/workflows/cmake.yml | 5 ++++- tools/cmake/CPM.cmake | 24 ++++++++++++++++++++++++ tools/cmake/setvars.cmake | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tools/cmake/CPM.cmake diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 8de34ca7..cf41b5c9 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -21,7 +21,10 @@ jobs: submodules: recursive - name: Build - uses: threeal/cmake-action@v2.0.0 + uses: threeal/cmake-action@v2.1.0 with: source-dir: ${{env.unit_test_dir}} + - name: Test + uses: threeal/ctest-action@v1.1.0 + diff --git a/tools/cmake/CPM.cmake b/tools/cmake/CPM.cmake new file mode 100644 index 00000000..baf2d8c3 --- /dev/null +++ b/tools/cmake/CPM.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.40.2) +set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/tools/cmake/setvars.cmake b/tools/cmake/setvars.cmake index 43c3c478..8b75db8e 100644 --- a/tools/cmake/setvars.cmake +++ b/tools/cmake/setvars.cmake @@ -1,6 +1,9 @@ +include_guard() + get_filename_component(TOOLS_DIR ${CMAKE_CURRENT_LIST_DIR} ABSOLUTE) get_filename_component(ROOT_DIR ${TOOLS_DIR}/../.. ABSOLUTE) set(ESTD_DIR ${ROOT_DIR}/src) +include(${TOOLS_DIR}/CPM.cmake) include(${TOOLS_DIR}/fetchcontent.cmake) include(${TOOLS_DIR}/options.cmake) From e37de57e0c0d519b99eb966a393830270468cbfd Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Fri, 6 Dec 2024 23:31:17 -0800 Subject: [PATCH 15/15] build: fiddling with CTest folder --- .github/workflows/cmake.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index cf41b5c9..c02fd0d7 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.2.2 with: submodules: recursive @@ -27,4 +27,7 @@ jobs: - name: Test uses: threeal/ctest-action@v1.1.0 + with: + # DEBT: Grab "build-dir" from above cmake-action + test-dir: ${{env.unit_test_dir}}/build