From a26118fb99e6b8ccfc3bf9261f59bc5edb453a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sat, 14 Oct 2023 11:23:36 +0200 Subject: [PATCH 1/7] preliminary module support (snapshot) --- CMakeLists.txt | 36 +++++++++++++++++-------------- Makefile | 4 ++-- include/ctll/fixed_string.hpp | 2 ++ include/ctll/grammars.hpp | 10 ++++----- include/ctll/parser.hpp | 2 ++ include/ctll/utilities.hpp | 2 ++ include/ctre.cppm | 11 ++++++++++ include/ctre/atoms.hpp | 3 +++ include/ctre/atoms_characters.hpp | 3 +++ include/ctre/evaluation.hpp | 3 +++ include/ctre/functions.hpp | 4 ++-- include/ctre/id.hpp | 2 ++ include/ctre/iterators.hpp | 3 +++ include/ctre/pcre_actions.hpp | 3 +++ include/ctre/return_type.hpp | 3 +++ include/ctre/std_includes.hpp | 18 ++++++++++++++++ include/ctre/utf8.hpp | 3 +++ include/ctre/utility.hpp | 6 ++++++ include/ctre/wrapper.hpp | 35 ++++++++++++++++-------------- module-test.cpp | 9 ++++++++ tests/api.cpp | 11 ++++++++++ 21 files changed, 132 insertions(+), 41 deletions(-) create mode 100644 include/ctre.cppm create mode 100644 include/ctre/std_includes.hpp create mode 100644 module-test.cpp create mode 100644 tests/api.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a60ca89f..40a6840a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ -cmake_minimum_required(VERSION 3.8.0) +cmake_minimum_required(VERSION 3.28) # When updating to a newer version of CMake, see if we can use the following project(ctre HOMEPAGE_URL "https://compile-time.re" - VERSION 3.0 + VERSION 3.9 LANGUAGES CXX) set(PROJECT_DESCRIPTION "Fast compile-time regular expressions with support for matching/searching/capturing during compile-time or runtime.") @@ -25,10 +25,12 @@ cmake_dependent_option(CTRE_BUILD_PACKAGE_RPM "Create RPM Package (${PROJECT_NAME})" ON "CTRE_BUILD_PACKAGE;CTRE_RPMBUILD_FOUND" OFF) -add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME} STATIC) add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -target_include_directories(${PROJECT_NAME} INTERFACE +target_sources(${PROJECT_NAME} PUBLIC FILE_SET sources TYPE CXX_MODULES FILES include/ctre.cppm) + +target_include_directories(${PROJECT_NAME} PUBLIC $ $) @@ -36,9 +38,9 @@ if (NOT CTRE_CXX_STANDARD) set(CTRE_CXX_STANDARD 20) endif() -target_compile_features(ctre INTERFACE cxx_std_${CTRE_CXX_STANDARD}) +target_compile_features(ctre PUBLIC cxx_std_${CTRE_CXX_STANDARD}) -install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets) +#install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets) if (NOT EXISTS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in") file(WRITE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in [[ @@ -58,19 +60,21 @@ write_basic_package_version_file(ctre-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) -install(EXPORT ${PROJECT_NAME}-targets - DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}" - NAMESPACE ${PROJECT_NAME}::) -install( - FILES - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" - DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}) -install(DIRECTORY include/ DESTINATION include - FILES_MATCHING PATTERN *.hpp) +#install(EXPORT ${PROJECT_NAME}-targets +# DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}" +# NAMESPACE ${PROJECT_NAME}::) +#install( +# FILES +# "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" +# "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" +# DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}) +#install(DIRECTORY include/ DESTINATION include +# FILES_MATCHING PATTERN *.hpp) if(CTRE_BUILD_TESTS) add_subdirectory(tests) + add_executable(module-test module-test.cpp) + target_link_libraries(module-test ${PROJECT_NAME}) endif() if (NOT CTRE_BUILD_PACKAGE) diff --git a/Makefile b/Makefile index a2016f74..609f396b 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ single-header/unicode-db.hpp: include/unicode-db/unicode-db.hpp cp $+ $@ single-header/ctre.hpp: - python3 -m quom include/ctre.hpp ctre.hpp.tmp + python3.9 -m quom include/ctre.hpp ctre.hpp.tmp echo "/*" > single-header/ctre.hpp cat LICENSE >> single-header/ctre.hpp echo "*/" >> single-header/ctre.hpp @@ -75,7 +75,7 @@ single-header/ctre.hpp: rm ctre.hpp.tmp single-header/ctre-unicode.hpp: - python3 -m quom include/ctre-unicode.hpp ctre-unicode.hpp.tmp + python3.9 -m quom include/ctre-unicode.hpp ctre-unicode.hpp.tmp echo "/*" > single-header/ctre-unicode.hpp cat LICENSE >> single-header/ctre-unicode.hpp echo "*/" >> single-header/ctre-unicode.hpp diff --git a/include/ctll/fixed_string.hpp b/include/ctll/fixed_string.hpp index 0a87171c..f747a63b 100644 --- a/include/ctll/fixed_string.hpp +++ b/include/ctll/fixed_string.hpp @@ -1,11 +1,13 @@ #ifndef CTLL__FIXED_STRING__GPP #define CTLL__FIXED_STRING__GPP +#ifndef CTLL_IN_MODULE #include #include #include #include #include +#endif namespace ctll { diff --git a/include/ctll/grammars.hpp b/include/ctll/grammars.hpp index 2d5c2c0b..95f318f8 100644 --- a/include/ctll/grammars.hpp +++ b/include/ctll/grammars.hpp @@ -57,7 +57,7 @@ struct anything { template struct range { constexpr inline range() noexcept { } //template constexpr range(term) noexcept requires (A <= V) && (V <= B); - template > constexpr inline range(term) noexcept; + template > constexpr inline range(term) noexcept { } }; #ifdef __EDG__ @@ -70,9 +70,9 @@ template struct contains { template struct set { constexpr inline set() noexcept { } #ifdef __EDG__ - template ::value>> constexpr inline set(term) noexcept; + template ::value>> constexpr inline set(term) noexcept { } #else - template > constexpr inline set(term) noexcept; + template > constexpr inline set(term) noexcept { } #endif }; @@ -81,9 +81,9 @@ template struct neg_set { constexpr inline neg_set() noexcept { } #ifdef __EDG__ - template ::value>> constexpr inline neg_set(term) noexcept; + template ::value>> constexpr inline neg_set(term) noexcept { } #else - template > constexpr inline neg_set(term) noexcept; + template > constexpr inline neg_set(term) noexcept { } #endif }; diff --git a/include/ctll/parser.hpp b/include/ctll/parser.hpp index b355eb1e..924be67a 100644 --- a/include/ctll/parser.hpp +++ b/include/ctll/parser.hpp @@ -6,7 +6,9 @@ #include "grammars.hpp" #include "actions.hpp" +#ifndef CTLL_IN_MODULE #include +#endif namespace ctll { diff --git a/include/ctll/utilities.hpp b/include/ctll/utilities.hpp index fbb9f37f..57fafab7 100644 --- a/include/ctll/utilities.hpp +++ b/include/ctll/utilities.hpp @@ -1,7 +1,9 @@ #ifndef CTLL__UTILITIES__HPP #define CTLL__UTILITIES__HPP +#ifndef CTLL_IN_MODULE #include +#endif #if defined __cpp_nontype_template_parameter_class #define CTLL_CNTTP_COMPILER_CHECK 1 diff --git a/include/ctre.cppm b/include/ctre.cppm new file mode 100644 index 00000000..82ff208b --- /dev/null +++ b/include/ctre.cppm @@ -0,0 +1,11 @@ +module; + +#include "ctre/std_includes.hpp" + +export module ctre; + +#define CTRE_IN_MODULE +#define CTLL_IN_MODULE + +#include "ctre.hpp" + diff --git a/include/ctre/atoms.hpp b/include/ctre/atoms.hpp index c4381c6f..10c72b73 100644 --- a/include/ctre/atoms.hpp +++ b/include/ctre/atoms.hpp @@ -2,7 +2,10 @@ #define CTRE__ATOMS__HPP #include "atoms_characters.hpp" + +#ifndef CTRE_IN_MODULE #include +#endif namespace ctre { diff --git a/include/ctre/atoms_characters.hpp b/include/ctre/atoms_characters.hpp index d1938e50..98d39385 100644 --- a/include/ctre/atoms_characters.hpp +++ b/include/ctre/atoms_characters.hpp @@ -3,7 +3,10 @@ #include "utility.hpp" #include "flags_and_modes.hpp" + +#ifndef CTRE_IN_MODULE #include +#endif namespace ctre { diff --git a/include/ctre/evaluation.hpp b/include/ctre/evaluation.hpp index d2f329e9..4f9c5cb4 100644 --- a/include/ctre/evaluation.hpp +++ b/include/ctre/evaluation.hpp @@ -9,7 +9,10 @@ #include "return_type.hpp" #include "find_captures.hpp" #include "first.hpp" + +#ifndef CTRE_IN_MODULE #include +#endif // remove me when MSVC fix the constexpr bug #ifdef _MSC_VER diff --git a/include/ctre/functions.hpp b/include/ctre/functions.hpp index dfda9857..157400c1 100644 --- a/include/ctre/functions.hpp +++ b/include/ctre/functions.hpp @@ -11,7 +11,7 @@ namespace ctre { #if !CTRE_CNTTP_COMPILER_CHECK // avoiding CTAD limitation in C++17 -template class pattern: public ctll::fixed_string { +CTRE_EXPORT template class pattern: public ctll::fixed_string { using parent = ctll::fixed_string; public: constexpr pattern(const CharT (&input)[N]) noexcept: parent(input) { } @@ -20,7 +20,7 @@ template class pattern: public ctll::fixed_string template pattern(const CharT (&)[N]) -> pattern; // for better examples -template class fixed_string: public ctll::fixed_string { +CTRE_EXPORT template class fixed_string: public ctll::fixed_string { using parent = ctll::fixed_string; public: constexpr fixed_string(const CharT (&input)[N]) noexcept: parent(input) { } diff --git a/include/ctre/id.hpp b/include/ctre/id.hpp index 2d2ca9ae..50f244e6 100644 --- a/include/ctre/id.hpp +++ b/include/ctre/id.hpp @@ -1,7 +1,9 @@ #ifndef CTRE__ID__HPP #define CTRE__ID__HPP +#ifndef CTRE_IN_MODULE #include +#endif namespace ctre { diff --git a/include/ctre/iterators.hpp b/include/ctre/iterators.hpp index 35a1b6dd..3ff7684c 100644 --- a/include/ctre/iterators.hpp +++ b/include/ctre/iterators.hpp @@ -3,7 +3,10 @@ #include "literals.hpp" #include "wrapper.hpp" + +#ifndef CTRE_IN_MODULE #include +#endif namespace ctre { diff --git a/include/ctre/pcre_actions.hpp b/include/ctre/pcre_actions.hpp index a221968a..ec35a768 100644 --- a/include/ctre/pcre_actions.hpp +++ b/include/ctre/pcre_actions.hpp @@ -4,8 +4,11 @@ #include "pcre.hpp" #include "rotate.hpp" #include "id.hpp" + +#ifndef CTRE_IN_MODULE #include #include +#endif namespace ctre { diff --git a/include/ctre/return_type.hpp b/include/ctre/return_type.hpp index 01a64cfd..2c11e83a 100644 --- a/include/ctre/return_type.hpp +++ b/include/ctre/return_type.hpp @@ -3,6 +3,8 @@ #include "id.hpp" #include "utf8.hpp" + +#ifndef CTRE_IN_MODULE #include #include #include @@ -12,6 +14,7 @@ #if __has_include() #include #endif +#endif namespace ctre { diff --git a/include/ctre/std_includes.hpp b/include/ctre/std_includes.hpp new file mode 100644 index 00000000..74e117dd --- /dev/null +++ b/include/ctre/std_includes.hpp @@ -0,0 +1,18 @@ +#ifndef CTRE_STD_INCLUDES_HPP +#define CTRE_STD_INCLUDES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +#include +#endif + +#endif diff --git a/include/ctre/utf8.hpp b/include/ctre/utf8.hpp index 886657eb..be514ed3 100644 --- a/include/ctre/utf8.hpp +++ b/include/ctre/utf8.hpp @@ -4,8 +4,11 @@ #if __cpp_char8_t >= 201811 #include "utility.hpp" + +#ifndef CTRE_IN_MODULE #include #include +#endif #if __cpp_lib_char8_t >= 201811L #define CTRE_ENABLE_UTF8_RANGE diff --git a/include/ctre/utility.hpp b/include/ctre/utility.hpp index 13b935f6..b3f96170 100644 --- a/include/ctre/utility.hpp +++ b/include/ctre/utility.hpp @@ -3,6 +3,12 @@ #include "../ctll/utilities.hpp" +#ifdef CTRE_IN_MODULE +#define CTRE_EXPORT export +#else +#define CTRE_EXPORT +#endif + #define CTRE_CNTTP_COMPILER_CHECK CTLL_CNTTP_COMPILER_CHECK #if __GNUC__ > 9 diff --git a/include/ctre/wrapper.hpp b/include/ctre/wrapper.hpp index 55e35b48..4106e148 100644 --- a/include/ctre/wrapper.hpp +++ b/include/ctre/wrapper.hpp @@ -6,7 +6,10 @@ #include "utf8.hpp" #include "return_type.hpp" #include "range.hpp" + +#ifndef CTRE_IN_MODULE #include +#endif namespace ctre { @@ -303,39 +306,39 @@ template struct regex_builder { // case-sensitive -template static constexpr inline auto match = regular_expression::type, match_method, ctll::list>(); +CTRE_EXPORT template constexpr auto match = regular_expression::type, match_method, ctll::list>(); -template static constexpr inline auto search = regular_expression::type, search_method, ctll::list>(); +CTRE_EXPORT template constexpr auto search = regular_expression::type, search_method, ctll::list>(); -template static constexpr inline auto starts_with = regular_expression::type, starts_with_method, ctll::list>(); +CTRE_EXPORT template constexpr auto starts_with = regular_expression::type, starts_with_method, ctll::list>(); -template static constexpr inline auto range = regular_expression::type, range_method, ctll::list>(); +CTRE_EXPORT template constexpr auto range = regular_expression::type, range_method, ctll::list>(); -template static constexpr inline auto split = regular_expression::type, split_method, ctll::list>(); +CTRE_EXPORT template constexpr auto split = regular_expression::type, split_method, ctll::list>(); -template static constexpr inline auto tokenize = regular_expression::type, tokenize_method, ctll::list>(); +CTRE_EXPORT template constexpr auto tokenize = regular_expression::type, tokenize_method, ctll::list>(); -template static constexpr inline auto iterator = regular_expression::type, iterator_method, ctll::list>(); +CTRE_EXPORT template constexpr auto iterator = regular_expression::type, iterator_method, ctll::list>(); -static constexpr inline auto sentinel = regex_end_iterator(); +CTRE_EXPORT constexpr auto sentinel = regex_end_iterator(); // multiline -template static constexpr inline auto multiline_match = regular_expression::type, match_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_match = regular_expression::type, match_method, ctll::list>(); -template static constexpr inline auto multiline_search = regular_expression::type, search_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_search = regular_expression::type, search_method, ctll::list>(); -template static constexpr inline auto multiline_starts_with = regular_expression::type, starts_with_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_starts_with = regular_expression::type, starts_with_method, ctll::list>(); -template static constexpr inline auto multiline_range = regular_expression::type, range_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_range = regular_expression::type, range_method, ctll::list>(); -template static constexpr inline auto multiline_split = regular_expression::type, split_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_split = regular_expression::type, split_method, ctll::list>(); -template static constexpr inline auto multiline_tokenize = regular_expression::type, tokenize_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_tokenize = regular_expression::type, tokenize_method, ctll::list>(); -template static constexpr inline auto multiline_iterator = regular_expression::type, iterator_method, ctll::list>(); +CTRE_EXPORT template constexpr auto multiline_iterator = regular_expression::type, iterator_method, ctll::list>(); -static constexpr inline auto multiline_sentinel = regex_end_iterator(); +CTRE_EXPORT constexpr auto multiline_sentinel = regex_end_iterator(); } diff --git a/module-test.cpp b/module-test.cpp new file mode 100644 index 00000000..b869043c --- /dev/null +++ b/module-test.cpp @@ -0,0 +1,9 @@ +import ctre; + +bool match(std::string_view subject) { + return ctre::match<"[0-9]+">(subject); +} + +int main() { + return !match("12345"); +} \ No newline at end of file diff --git a/tests/api.cpp b/tests/api.cpp new file mode 100644 index 00000000..1cd2a3e2 --- /dev/null +++ b/tests/api.cpp @@ -0,0 +1,11 @@ +#include +#include "ctre.hpp" + +int do_something(std::string_view) { + return 42; +} + +int test(std::string_view in) { + ctre::range<"abc">(in) | std::views::transform(do_something); + return 41; +} \ No newline at end of file From 158227369eeb35f2a4eb0c0affe3802250ba9973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 10:18:36 +0200 Subject: [PATCH 2/7] further modularization --- include/ctre.cppm | 43 ++++++++++++++++--- include/ctre/functions.hpp | 4 +- .../ctre/{std_includes.hpp => std_module.hpp} | 13 +++++- include/ctre/utility.hpp | 6 --- include/ctre/wrapper.hpp | 38 ++++++++-------- module-test.cpp | 11 +++-- 6 files changed, 79 insertions(+), 36 deletions(-) rename include/ctre/{std_includes.hpp => std_module.hpp} (59%) diff --git a/include/ctre.cppm b/include/ctre.cppm index 82ff208b..ca9394c9 100644 --- a/include/ctre.cppm +++ b/include/ctre.cppm @@ -1,11 +1,44 @@ module; -#include "ctre/std_includes.hpp" +// this will enable in-module mode and include/import std library +#include "ctre/std_module.hpp" +// CTRE in in-module mode won't include anything +#include "ctre.hpp" export module ctre; -#define CTRE_IN_MODULE -#define CTLL_IN_MODULE - -#include "ctre.hpp" +// this won't export everything in ctre namespace, but only things I take here... +export namespace ctre { + // so you can pipe a range into a regex wrapper (for split) + using ctre::operator|; + + // modifiers + using ctre::singleline; + using ctre::multiline; + // singleline niebloids + using ctre::match; + using ctre::search; + using ctre::starts_with; + + // singleline range niebloids + using ctre::search_all; + using ctre::range; + using ctre::split; + using ctre::tokenize; + using ctre::iterator; + using ctre::sentinel; + + // multiline niebloids + using ctre::multiline_match; + using ctre::multiline_search; + using ctre::multiline_starts_with; + + // multiline range niebloids + using ctre::multiline_search_all; + using ctre::multiline_range; + using ctre::multiline_split; + using ctre::multiline_tokenize; + using ctre::multiline_iterator; + using ctre::multiline_sentinel; +} diff --git a/include/ctre/functions.hpp b/include/ctre/functions.hpp index 157400c1..dfda9857 100644 --- a/include/ctre/functions.hpp +++ b/include/ctre/functions.hpp @@ -11,7 +11,7 @@ namespace ctre { #if !CTRE_CNTTP_COMPILER_CHECK // avoiding CTAD limitation in C++17 -CTRE_EXPORT template class pattern: public ctll::fixed_string { +template class pattern: public ctll::fixed_string { using parent = ctll::fixed_string; public: constexpr pattern(const CharT (&input)[N]) noexcept: parent(input) { } @@ -20,7 +20,7 @@ CTRE_EXPORT template class pattern: public ctll::fixe template pattern(const CharT (&)[N]) -> pattern; // for better examples -CTRE_EXPORT template class fixed_string: public ctll::fixed_string { +template class fixed_string: public ctll::fixed_string { using parent = ctll::fixed_string; public: constexpr fixed_string(const CharT (&input)[N]) noexcept: parent(input) { } diff --git a/include/ctre/std_includes.hpp b/include/ctre/std_module.hpp similarity index 59% rename from include/ctre/std_includes.hpp rename to include/ctre/std_module.hpp index 74e117dd..dfff7dd8 100644 --- a/include/ctre/std_includes.hpp +++ b/include/ctre/std_module.hpp @@ -1,5 +1,9 @@ -#ifndef CTRE_STD_INCLUDES_HPP -#define CTRE_STD_INCLUDES_HPP +#ifndef CTRE_STD_MODULE_HPP +#define CTRE_STD_MODULE_HPP + +#if __cpp_lib_modules >= 202207L +import std; +#else #include #include @@ -16,3 +20,8 @@ #endif #endif + +#define CTRE_IN_MODULE +#define CTLL_IN_MODULE + +#endif diff --git a/include/ctre/utility.hpp b/include/ctre/utility.hpp index b3f96170..13b935f6 100644 --- a/include/ctre/utility.hpp +++ b/include/ctre/utility.hpp @@ -3,12 +3,6 @@ #include "../ctll/utilities.hpp" -#ifdef CTRE_IN_MODULE -#define CTRE_EXPORT export -#else -#define CTRE_EXPORT -#endif - #define CTRE_CNTTP_COMPILER_CHECK CTLL_CNTTP_COMPILER_CHECK #if __GNUC__ > 9 diff --git a/include/ctre/wrapper.hpp b/include/ctre/wrapper.hpp index 4106e148..ae86238a 100644 --- a/include/ctre/wrapper.hpp +++ b/include/ctre/wrapper.hpp @@ -274,7 +274,7 @@ template constexpr auto operato template constexpr auto operator|(Range && range, regular_expression re) noexcept { return re.multi_exec(std::forward(range)); -} +}; // error reporting of problematic position in a regex template struct problem_at_position; // do not define! @@ -306,39 +306,43 @@ template struct regex_builder { // case-sensitive -CTRE_EXPORT template constexpr auto match = regular_expression::type, match_method, ctll::list>(); +template constexpr auto match = regular_expression::type, match_method, ctll::list>(); -CTRE_EXPORT template constexpr auto search = regular_expression::type, search_method, ctll::list>(); +template constexpr auto search = regular_expression::type, search_method, ctll::list>(); -CTRE_EXPORT template constexpr auto starts_with = regular_expression::type, starts_with_method, ctll::list>(); +template constexpr auto starts_with = regular_expression::type, starts_with_method, ctll::list>(); -CTRE_EXPORT template constexpr auto range = regular_expression::type, range_method, ctll::list>(); +template constexpr auto search_all = regular_expression::type, range_method, ctll::list>(); -CTRE_EXPORT template constexpr auto split = regular_expression::type, split_method, ctll::list>(); +template constexpr auto range = search_all; -CTRE_EXPORT template constexpr auto tokenize = regular_expression::type, tokenize_method, ctll::list>(); +template constexpr auto split = regular_expression::type, split_method, ctll::list>(); -CTRE_EXPORT template constexpr auto iterator = regular_expression::type, iterator_method, ctll::list>(); +template constexpr auto tokenize = regular_expression::type, tokenize_method, ctll::list>(); -CTRE_EXPORT constexpr auto sentinel = regex_end_iterator(); +template constexpr auto iterator = regular_expression::type, iterator_method, ctll::list>(); + +constexpr inline auto sentinel = regex_end_iterator(); // multiline -CTRE_EXPORT template constexpr auto multiline_match = regular_expression::type, match_method, ctll::list>(); +template constexpr auto multiline_match = regular_expression::type, match_method, ctll::list>(); + +template constexpr auto multiline_search = regular_expression::type, search_method, ctll::list>(); -CTRE_EXPORT template constexpr auto multiline_search = regular_expression::type, search_method, ctll::list>(); +template constexpr auto multiline_starts_with = regular_expression::type, starts_with_method, ctll::list>(); -CTRE_EXPORT template constexpr auto multiline_starts_with = regular_expression::type, starts_with_method, ctll::list>(); +template constexpr auto multiline_search_all = regular_expression::type, range_method, ctll::list>(); -CTRE_EXPORT template constexpr auto multiline_range = regular_expression::type, range_method, ctll::list>(); +template constexpr auto multiline_range = multiline_search_all; -CTRE_EXPORT template constexpr auto multiline_split = regular_expression::type, split_method, ctll::list>(); +template constexpr auto multiline_split = regular_expression::type, split_method, ctll::list>(); -CTRE_EXPORT template constexpr auto multiline_tokenize = regular_expression::type, tokenize_method, ctll::list>(); +template constexpr auto multiline_tokenize = regular_expression::type, tokenize_method, ctll::list>(); -CTRE_EXPORT template constexpr auto multiline_iterator = regular_expression::type, iterator_method, ctll::list>(); +template constexpr auto multiline_iterator = regular_expression::type, iterator_method, ctll::list>(); -CTRE_EXPORT constexpr auto multiline_sentinel = regex_end_iterator(); +constexpr inline auto multiline_sentinel = regex_end_iterator(); } diff --git a/module-test.cpp b/module-test.cpp index b869043c..10548bbf 100644 --- a/module-test.cpp +++ b/module-test.cpp @@ -1,9 +1,12 @@ import ctre; -bool match(std::string_view subject) { - return ctre::match<"[0-9]+">(subject); -} +#include +#include int main() { - return !match("12345"); + for (auto item: "123456 2313 23132" | ctre::search_all<"[0-9]++">) { + std::cout << item << "\n"; + } + + return 0; } \ No newline at end of file From 39e636a09978819f1a8b795ca13b7d5d9ed4d5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 10:21:21 +0200 Subject: [PATCH 3/7] more comments --- include/ctre.cppm | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/include/ctre.cppm b/include/ctre.cppm index ca9394c9..e8c537bb 100644 --- a/include/ctre.cppm +++ b/include/ctre.cppm @@ -17,18 +17,16 @@ export namespace ctre { using ctre::multiline; // singleline niebloids - using ctre::match; - using ctre::search; - using ctre::starts_with; + using ctre::match; // whole input range must match regex + using ctre::search; // input subrange must match regex + using ctre::starts_with; // prefix of input must match regex // singleline range niebloids - using ctre::search_all; - using ctre::range; - using ctre::split; - using ctre::tokenize; - using ctre::iterator; - using ctre::sentinel; - + using ctre::search_all; // will look for each occurence of regex + using ctre::range; // alias to search_all + using ctre::split; // will split input range by the regex + using ctre::tokenize; // will split input to pieces matching regex + // multiline niebloids using ctre::multiline_match; using ctre::multiline_search; @@ -39,6 +37,4 @@ export namespace ctre { using ctre::multiline_range; using ctre::multiline_split; using ctre::multiline_tokenize; - using ctre::multiline_iterator; - using ctre::multiline_sentinel; } From 5748cdbda668c5eb95d7ec5e4833d65c9a16ba13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 10:22:15 +0200 Subject: [PATCH 4/7] update of a comment --- include/ctre.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ctre.cppm b/include/ctre.cppm index e8c537bb..020122cd 100644 --- a/include/ctre.cppm +++ b/include/ctre.cppm @@ -9,7 +9,7 @@ export module ctre; // this won't export everything in ctre namespace, but only things I take here... export namespace ctre { - // so you can pipe a range into a regex wrapper (for split) + // so you can pipe a range into a regex wrapper using ctre::operator|; // modifiers From 2622bd71bc79f11bdf69c378d5ec4866812b86a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 21:26:29 +0200 Subject: [PATCH 5/7] custom tuple --- .github/workflows/untitled.txt | 0 include/ctre/capture_tuple.hpp | 346 +++++++++++++++++++++++++++++++++ include/ctre/evaluation.hpp | 6 +- include/ctre/find_captures.hpp | 6 +- include/ctre/return_type.hpp | 41 ++-- include/ctre/wrapper.hpp | 2 +- 6 files changed, 384 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/untitled.txt create mode 100644 include/ctre/capture_tuple.hpp diff --git a/.github/workflows/untitled.txt b/.github/workflows/untitled.txt new file mode 100644 index 00000000..e69de29b diff --git a/include/ctre/capture_tuple.hpp b/include/ctre/capture_tuple.hpp new file mode 100644 index 00000000..8bb9330f --- /dev/null +++ b/include/ctre/capture_tuple.hpp @@ -0,0 +1,346 @@ +#ifndef CTRE__CAPTURE_TUPLE__HPP +#define CTRE__CAPTURE_TUPLE__HPP + +#include "id.hpp" +#include "utf8.hpp" + +#ifndef CTRE_IN_MODULE +#include +#include +#include +#include +#include +#include +#if __has_include() +#include +#endif +#if __has_include() +#include +#endif +#endif + +namespace ctre { + +template struct capture_number_id { }; +template struct capture_name_id { }; + +struct no_capture_selected { + template constexpr friend auto operator+(no_capture_selected, T & rhs) -> T & { + return rhs; + } + template constexpr friend auto operator+(T & lhs, no_capture_selected) -> T & { + return lhs; + } + template constexpr friend auto operator+(no_capture_selected, const T & rhs) -> const T & { + return rhs; + } + template constexpr friend auto operator+(const T & lhs, no_capture_selected) -> const T & { + return lhs; + } + constexpr friend auto operator+(no_capture_selected, no_capture_selected) -> no_capture_selected { + return {}; + } +}; + +template struct capture_identifier { + constexpr friend bool operator==(capture_identifier, capture_number_id) noexcept { + return true; + } + template constexpr friend bool operator==(capture_identifier, capture_number_id) noexcept { + return false; + } + constexpr friend bool operator==(capture_identifier, capture_name_id) noexcept { + return true; + } + template constexpr friend bool operator==(capture_identifier, capture_name_id) noexcept { + return false; + } +}; + +template struct capture_tuple_storage { + using iterator_type = Iterator; + + [[no_unique_address]] Iterator first{}; + [[no_unique_address]] Sentinel last{}; + + constexpr capture_tuple_storage() = default; + constexpr capture_tuple_storage(const capture_tuple_storage &) = default; + constexpr capture_tuple_storage(capture_tuple_storage &&) = default; + + constexpr capture_tuple_storage & operator=(const capture_tuple_storage &) = default; + constexpr capture_tuple_storage & operator=(capture_tuple_storage &&) = default; + + + constexpr bool matched() noexcept { + return true; // TODO + } +}; + +template struct capture_tuple_item { + using identifier_type = Id; + using storage_type = Storage; + + static_assert(std::move_constructible); + static_assert(std::copy_constructible); + + + [[no_unique_address]] storage_type storage{}; + + //constexpr capture_tuple_item() = default; + + template constexpr friend auto operator==(const capture_tuple_item & item, capture_number_id rhs) noexcept { + if constexpr (identifier_type{} == rhs) { + return item; + } else { + return no_capture_selected{}; + } + } + + template constexpr friend auto operator==(const capture_tuple_item & item, capture_name_id rhs) noexcept { + if constexpr (identifier_type{} == rhs) { + return item; + } else { + return no_capture_selected{}; + } + } + + template constexpr friend auto operator==(capture_tuple_item & item, capture_number_id rhs) noexcept { + if constexpr (identifier_type{} == rhs) { + return item; + } else { + return no_capture_selected{}; + } + } + + template constexpr friend auto operator==(capture_tuple_item & item, capture_name_id rhs) noexcept { + if constexpr (identifier_type{} == rhs) { + return item; + } else { + return no_capture_selected{}; + } + } +}; + +template struct foo { }; + +template struct identify; + +template constexpr decltype(auto) select_if(T && arg) { + if constexpr (Value) { + return std::forward(arg); + } else { + return no_capture_selected{}; + } +} + +template constexpr auto & select_nth(Ts && ... args) { + static_assert(I < sizeof...(Ts)); + + const auto lmb = [&](std::index_sequence) -> decltype(auto) { + //identify(std::forward(args)))...> i; + + return (no_capture_selected{} + ... + select_if(std::forward(args))); + }; + + //identify()))> i; + + return lmb(std::make_index_sequence()); +} + +template class tuple { + static constexpr auto build_storage(Ts... args) { + return [...items = std::move(args)](auto && fnc) mutable -> decltype(auto) { + return fnc(items...); + }; + } + + static constexpr auto default_storage() { + return build_storage(Ts{}...); + } + + static constexpr auto copy_storage(const Ts & ... args) { + return build_storage(args...); + } + + using storage_type = decltype(build_storage(Ts{}...)); + + mutable storage_type storage; + +public: + + static constexpr auto size = std::integral_constant{}; + + constexpr tuple() noexcept: storage{default_storage()}{ } + + constexpr tuple(Ts... args) noexcept: storage{build_storage(args...)} { } + + constexpr tuple(tuple && orig) noexcept: storage{std::move(orig.storage)} { } + + constexpr tuple(const tuple & orig) noexcept: storage{orig.storage([](const auto & ... rhs) { return build_storage(rhs...); })} { } + + constexpr tuple & operator=(const tuple & orig) noexcept { + storage([&](auto & ... lhs){ + orig.storage([&](const auto & ... rhs){ + ((void)(lhs = rhs), ...); + }); + }); + return *this; + } + + constexpr tuple & operator=(tuple && orig) noexcept { + storage([&](auto & ... lhs){ + orig.storage([&](auto & ... rhs){ + ((void)std::swap(lhs, rhs), ...); + }); + }); + return *this; + } + + constexpr ~tuple() noexcept = default; + + // comparison + constexpr friend bool operator==(const tuple & lhs, const tuple & rhs) noexcept { + return lhs.storage([&](const auto & ... lhs_value){ + return rhs.storage([&](const auto & ... rhs_value){ + return ((lhs_value == rhs_value) && ...); + }); + }); + } + + constexpr friend auto operator<=>(const tuple & lhs, const tuple & rhs) noexcept { + return lhs.storage([&](const auto & ... lhs_value){ + return rhs.storage([&](const auto & ... rhs_value){ + using result_type = std::common_comparison_category_t rhs_value)...>; + + auto r = result_type::equivalent; + + ((r = (lhs_value <=> rhs_value), std::is_eq(r)) && ...); + + return r; + }); + }); + } + + // printing + template friend auto & operator<<(std::basic_ostream & str, const tuple & tpl) { + if constexpr (size()) { + tpl.storage([&](const auto & first, const auto & ... tail) { + (str << first); + ((void)(str << ';' << tail), ...); + }); + } + + return str; + } + + // support for get + template constexpr auto & get() & noexcept requires (I < size()) { + return storage([](auto & ... value) -> decltype(auto) { + return select_nth(value...); + }); + } + + template constexpr const auto & get() const & noexcept requires (I < size()) { + return storage([](const auto & ... value) -> decltype(auto) { + return select_nth(value...); + }); + } + + template constexpr auto get() && noexcept requires (I < size()) { + return storage([](auto & ... value) -> decltype(auto) { + return select_nth(std::move(value)...); + }); + } + + template constexpr auto get() const && noexcept requires (I < size()) { + return storage([](const auto & ... value) -> decltype(auto) { + return select_nth(std::move(value)...); + }); + } +}; + +template constexpr auto get = [](auto && tpl) noexcept -> decltype(auto) { + return tpl.get(); +}; + +template struct capture_tuple { + static constexpr auto build_lambda() { + return [...items = foo{}]() { + //return ((items == Id{}) + ... + no_capture_selected{}); + }; + } + + using tuple_storage_type = decltype(build_lambda()); + + tuple_storage_type internal_tuple{build_lambda()}; + + constexpr capture_tuple(...) noexcept { } + constexpr capture_tuple(const capture_tuple &) noexcept { } + constexpr capture_tuple(capture_tuple &&) noexcept { } + + constexpr capture_tuple & operator=(const capture_tuple & other) noexcept { + internal_tuple = other.internal_tuple; + return *this; + } + constexpr capture_tuple & operator=(capture_tuple && other) noexcept { + internal_tuple = std::move(other.internal_tuple); + return *this; + } + + constexpr capture_tuple & matched() noexcept { + // TODO + return *this; + } + + constexpr capture_tuple & unmatch() noexcept { + // TODO + return *this; + } + + + constexpr auto get_end_position() const noexcept { + return typename Storage::iterator_type{}; + } + + constexpr operator bool() const noexcept { + return true; + } + + template constexpr capture_tuple & start_capture(const typename Storage::iterator_type &) noexcept { + return *this; + } + + template constexpr capture_tuple & end_capture(const typename Storage::iterator_type &) noexcept { + return *this; + } + + + constexpr capture_tuple & set_start_mark(const typename Storage::iterator_type &) noexcept { + return *this; + } + + constexpr capture_tuple & set_end_mark(const typename Storage::iterator_type &) noexcept { + return *this; + } +}; + +template capture_tuple(Iterator, ctll::list) -> capture_tuple, CapturesIds...>; + +template using return_type = decltype(capture_tuple(std::declval(), find_captures(Pattern{}))); + +} + +namespace std { + +template struct tuple_size> : public decltype(ctre::tuple::size) { }; + +template struct tuple_element> { +public: + using type = decltype( + std::declval &>().template get() + ); +}; + +} + +#endif \ No newline at end of file diff --git a/include/ctre/evaluation.hpp b/include/ctre/evaluation.hpp index 4f9c5cb4..b7c3b393 100644 --- a/include/ctre/evaluation.hpp +++ b/include/ctre/evaluation.hpp @@ -6,7 +6,7 @@ #include "atoms_unicode.hpp" #include "starts_with_anchor.hpp" #include "utility.hpp" -#include "return_type.hpp" +#include "capture_tuple.hpp" #include "find_captures.hpp" #include "first.hpp" @@ -22,6 +22,10 @@ #endif namespace ctre { + +struct not_matched_tag_t { }; + +constexpr inline auto not_matched = not_matched_tag_t{}; template constexpr CTRE_FORCE_INLINE bool less_than_or_infinite([[maybe_unused]] size_t i) noexcept { if constexpr (Limit == 0) { diff --git a/include/ctre/find_captures.hpp b/include/ctre/find_captures.hpp index e6c49e26..58de1e8d 100644 --- a/include/ctre/find_captures.hpp +++ b/include/ctre/find_captures.hpp @@ -4,7 +4,7 @@ #include "atoms_characters.hpp" #include "atoms_unicode.hpp" #include "utility.hpp" -#include "return_type.hpp" +#include "capture_tuple.hpp" namespace ctre { @@ -112,12 +112,12 @@ template constexpr auto template constexpr auto find_captures(ctll::list, Tail...>, ctll::list) noexcept { - return find_captures(ctll::list(), ctll::list>()); + return find_captures(ctll::list(), ctll::list>()); } template constexpr auto find_captures(ctll::list, Tail...>, ctll::list) noexcept { - return find_captures(ctll::list(), ctll::list>()); + return find_captures(ctll::list(), ctll::list>()); } diff --git a/include/ctre/return_type.hpp b/include/ctre/return_type.hpp index 2c11e83a..81e591ad 100644 --- a/include/ctre/return_type.hpp +++ b/include/ctre/return_type.hpp @@ -14,6 +14,9 @@ #if __has_include() #include #endif +#if __has_include() +#include +#endif #endif namespace ctre { @@ -40,7 +43,7 @@ template struct captured_content { public: using char_type = typename std::iterator_traits::value_type; - using name = Name; + //using name = Name; constexpr CTRE_FORCE_INLINE storage() noexcept {} @@ -120,8 +123,6 @@ template struct captured_content { } #endif - template struct identify; - template constexpr CTRE_FORCE_INLINE auto to_view() const noexcept { // random access, because C++ (waving hands around) constexpr bool must_be_nonreverse_contiguous_iterator = is_random_accessible>::iterator_category> && !is_reverse_iterator; @@ -423,7 +424,6 @@ template using return_type = decltyp } -// support for structured bindings #ifndef __EDG__ #ifdef __clang__ @@ -431,16 +431,33 @@ template using return_type = decltyp #pragma clang diagnostic ignored "-Wmismatched-tags" #endif +// support for std::format + namespace std { - template struct tuple_size> : public std::integral_constant::count()> { }; + +#if __has_include() + //template struct formatter; - template struct tuple_element> { - public: - using type = decltype( - std::declval &>().template get() - ); - }; -} +template +struct formatter::template storage, CharT> +{ + +}; + +#endif + +// support for structured bindings + +template struct tuple_size> : public std::integral_constant::count()> { }; + +template struct tuple_element> { +public: + using type = decltype( + std::declval &>().template get() + ); +}; + +} // end of namespace std:: #ifdef __clang__ #pragma clang diagnostic pop diff --git a/include/ctre/wrapper.hpp b/include/ctre/wrapper.hpp index ae86238a..5b5a4a55 100644 --- a/include/ctre/wrapper.hpp +++ b/include/ctre/wrapper.hpp @@ -4,7 +4,7 @@ #include "evaluation.hpp" #include "utility.hpp" #include "utf8.hpp" -#include "return_type.hpp" +#include "capture_tuple.hpp" #include "range.hpp" #ifndef CTRE_IN_MODULE From e12ea4567f34fdafefcd26dfb6795586ebf4ec29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 21:49:07 +0200 Subject: [PATCH 6/7] fun with tuples --- include/ctre/capture_tuple.hpp | 11 +- include/ctre/tuple.hpp | 181 +++++++++++++++++++++++++++++++++ pokus2.cpp | 48 +++++++++ 3 files changed, 230 insertions(+), 10 deletions(-) create mode 100644 include/ctre/tuple.hpp create mode 100644 pokus2.cpp diff --git a/include/ctre/capture_tuple.hpp b/include/ctre/capture_tuple.hpp index 8bb9330f..a6d900e6 100644 --- a/include/ctre/capture_tuple.hpp +++ b/include/ctre/capture_tuple.hpp @@ -121,10 +121,6 @@ template struct capture_tuple_item { } }; -template struct foo { }; - -template struct identify; - template constexpr decltype(auto) select_if(T && arg) { if constexpr (Value) { return std::forward(arg); @@ -137,13 +133,9 @@ template constexpr auto & select_nth(Ts && ... args) static_assert(I < sizeof...(Ts)); const auto lmb = [&](std::index_sequence) -> decltype(auto) { - //identify(std::forward(args)))...> i; - return (no_capture_selected{} + ... + select_if(std::forward(args))); }; - //identify()))> i; - return lmb(std::make_index_sequence()); } @@ -225,8 +217,7 @@ template class tuple { template friend auto & operator<<(std::basic_ostream & str, const tuple & tpl) { if constexpr (size()) { tpl.storage([&](const auto & first, const auto & ... tail) { - (str << first); - ((void)(str << ';' << tail), ...); + ((str << first), ((void)(str << ' ' << tail), ...)); }); } diff --git a/include/ctre/tuple.hpp b/include/ctre/tuple.hpp new file mode 100644 index 00000000..b9d3de48 --- /dev/null +++ b/include/ctre/tuple.hpp @@ -0,0 +1,181 @@ +#ifndef CTRE_TUPLE_HPP +#define CTRE_TUPLE_HPP + +#ifndef CTRE_IN_MODULE +#include +#include +#include +#include +#include +#endif + +namespace ctre { + +struct no_tuple_element_selected { + template constexpr friend auto operator+(no_tuple_element_selected, T & rhs) -> T & { + return rhs; + } + template constexpr friend auto operator+(T & lhs, no_tuple_element_selected) -> T & { + return lhs; + } + template constexpr friend auto operator+(no_tuple_element_selected, const T & rhs) -> const T & { + return rhs; + } + template constexpr friend auto operator+(const T & lhs, no_tuple_element_selected) -> const T & { + return lhs; + } + constexpr friend auto operator+(no_tuple_element_selected, no_tuple_element_selected) -> no_tuple_element_selected { + return {}; + } +}; + +template constexpr auto select_if(T && arg) -> decltype(auto) { + if constexpr (Value) { + return std::forward(arg); + } else { + return no_tuple_element_selected{}; + } +} + +template constexpr auto select_nth(Ts && ... args) -> decltype(auto) { + static_assert(I < sizeof...(Ts)); + + return [&](std::index_sequence) -> decltype(auto) { + return (no_tuple_element_selected{} + ... + select_if(std::forward(args))); + }(std::make_index_sequence()); +} + +template class tuple { + static constexpr auto build_storage(Ts... args) { + return [...items = std::move(args)](auto && fnc) mutable -> decltype(auto) { + return fnc(items...); + }; + } + + static constexpr auto default_storage() { + return build_storage(Ts{}...); + } + + using storage_type = decltype(build_storage(std::declval()...)); + + mutable storage_type storage; + +public: + + static constexpr auto size = std::integral_constant{}; + + constexpr tuple() noexcept requires(std::default_initializable && ...): storage{default_storage()}{ } + + constexpr tuple(Ts... args) noexcept: storage{build_storage(args...)} { } + + constexpr tuple(tuple && orig) noexcept requires(std::move_constructible && ...): storage{std::move(orig.storage)} { } + + constexpr tuple(const tuple & orig) noexcept requires(std::copy_constructible && ...): storage{orig.storage([](const auto & ... rhs) { return build_storage(rhs...); })} { } + + constexpr tuple & operator=(const tuple & orig) noexcept requires(std::is_copy_assignable_v && ...) { + storage([&](auto & ... lhs){ + orig.storage([&](const auto & ... rhs){ + ((void)(lhs = rhs), ...); + }); + }); + return *this; + } + + constexpr tuple & operator=(tuple && orig) noexcept requires(std::is_move_assignable_v && ...) { + storage([&](auto & ... lhs){ + orig.storage([&](auto & ... rhs){ + ((void)std::swap(lhs, rhs), ...); + }); + }); + return *this; + } + + constexpr ~tuple() noexcept = default; + + // comparison + constexpr friend bool operator==(const tuple & lhs, const tuple & rhs) noexcept { + return lhs.storage([&](const auto & ... lhs_value){ + return rhs.storage([&](const auto & ... rhs_value){ + return ((lhs_value == rhs_value) && ...); + }); + }); + } + + constexpr friend auto operator<=>(const tuple & lhs, const tuple & rhs) noexcept { + return lhs.storage([&](const auto & ... lhs_value){ + return rhs.storage([&](const auto & ... rhs_value){ + using result_type = std::common_comparison_category_t rhs_value)...>; + + auto r = result_type::equivalent; + + ((r = (lhs_value <=> rhs_value), std::is_eq(r)) && ...); + + return r; + }); + }); + } + + // printing with iostream + template friend auto & operator<<(std::basic_ostream & str, const tuple & tpl) { + if constexpr (size()) { + tpl.storage([&](const auto & first, const auto & ... tail) { + ((str << first), ((void)(str << ' ' << tail), ...)); + }); + } + + return str; + } + + // support for get + template constexpr auto & get() & noexcept requires (I < size()) { + return storage([](auto & ... value) -> decltype(auto) { + return select_nth(value...); + }); + } + + template constexpr const auto & get() const & noexcept requires (I < size()) { + return storage([](const auto & ... value) -> decltype(auto) { + return select_nth(value...); + }); + } + + template constexpr auto get() && noexcept requires (I < size()) { + return storage([](auto & ... value) -> decltype(auto) { + return select_nth(std::move(value)...); + }); + } + + template constexpr auto get() const && noexcept requires (I < size()) { + return storage([](const auto & ... value) -> decltype(auto) { + return select_nth(std::move(value)...); + }); + } +}; + +// this is niebloid to avoid writing ctre::template get(tpl) +template constexpr auto get = [](auto && tpl) noexcept -> decltype(auto) { + return tpl.get(); +}; + +template constexpr auto tie(Ts & ... args) -> tuple { + return {args...}; +} + +} // namespace ctre + +// tuple protocol to support structured bindings + +namespace std { + +template struct tuple_size> : public decltype(ctre::tuple::size) { }; + +template struct tuple_element> { +public: + using type = decltype( + std::declval &>().template get() + ); +}; + +} // namespace std + +#endif \ No newline at end of file diff --git a/pokus2.cpp b/pokus2.cpp new file mode 100644 index 00000000..83f05e01 --- /dev/null +++ b/pokus2.cpp @@ -0,0 +1,48 @@ +#include +#include + +//bool match(std::string_view in) { +// auto r = ctre::search<"([a-z]+)">(in); +// return r; +//} + +const char * print_compare(auto val) { + if (std::is_eq(val)) { + return "=="; + } else if (std::is_lt(val)) { + return "<"; + } else if (std::is_gt(val)) { + return ">"; + } else { + return "!="; + } +} + +void print(const auto & a, const auto & b) { + std::cout << "(" << a << ") " << print_compare(a <=> b) << " (" << b << ")\n"; +} + +int main() { + + int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6; + + print(ctre::tie(a,b,c), ctre::tie(d,e,f)); + + ctre::tuple tpl{}; + ctre::tuple tpl1{1,2,3}; + ctre::tuple tpl2{tpl1}; + + print(tpl1, tpl2); + + ctre::tuple tpl3{std::move(tpl2)}; + + print(tpl2, tpl3); + + tpl3 = tpl; + + print(tpl3, tpl); + + tpl3 = std::move(tpl1); + + print(tpl3, tpl1); +} \ No newline at end of file From 8e632241247214712e1e52f6fabf27cd796a176f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= Date: Sun, 15 Oct 2023 21:52:20 +0200 Subject: [PATCH 7/7] add swap --- include/ctre/tuple.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/ctre/tuple.hpp b/include/ctre/tuple.hpp index b9d3de48..f081077d 100644 --- a/include/ctre/tuple.hpp +++ b/include/ctre/tuple.hpp @@ -84,12 +84,20 @@ template class tuple { constexpr tuple & operator=(tuple && orig) noexcept requires(std::is_move_assignable_v && ...) { storage([&](auto & ... lhs){ orig.storage([&](auto & ... rhs){ - ((void)std::swap(lhs, rhs), ...); + ((void)(lhs = std::move(rhs)), ...); }); }); return *this; } + constexpr void swap(tuple & other) noexcept { + storage([&](auto & ... lhs){ + other.storage([&](auto & ... rhs){ + ((void)std::swap(lhs, rhs), ...); + }); + }); + } + constexpr ~tuple() noexcept = default; // comparison