From b8078fdb324506d693f7cce8f3d0b13348ac6ed9 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 1 Feb 2025 12:11:22 +0100 Subject: [PATCH] Replace wildcards with something that is faster overall and for debug builds in particular --- src/common/filesystem/include/resourcefile.h | 3 +- src/common/filesystem/source/resourcefile.cpp | 55 +- src/common/filesystem/source/wildcards.hpp | 1833 ----------------- src/d_main.cpp | 3 +- 4 files changed, 51 insertions(+), 1843 deletions(-) delete mode 100644 src/common/filesystem/source/wildcards.hpp diff --git a/src/common/filesystem/include/resourcefile.h b/src/common/filesystem/include/resourcefile.h index a23914444..3d2da11b0 100644 --- a/src/common/filesystem/include/resourcefile.h +++ b/src/common/filesystem/include/resourcefile.h @@ -24,7 +24,8 @@ struct LumpFilterInfo std::vector reservedFolders; std::vector requiredPrefixes; std::vector embeddings; - std::vector blockednames; // File names that will never be accepted (e.g. dehacked.exe for Doom) + std::vector blockedextensions; // File extensions that will never be accepted (e.g. .exe and .bat) + std::vector blockedfolders; // File folders that will never be accepted (e.g. __macosx) std::function filenamecheck; // for scanning directories, this allows to eliminate unwanted content. std::function postprocessFunc; }; diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index 4b134cae5..3fd4676b0 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -43,7 +43,7 @@ #include "unicode.h" #include "fs_findfile.h" #include "fs_decompress.h" -#include "wildcards.hpp" +#include #include namespace FileSys { @@ -344,6 +344,46 @@ void FResourceFile::GenerateHash() } } +static bool IsBlockedExt(LumpFilterInfo* filter, const std::string_view& name) +{ + size_t extpos = name.find_last_of('.'); + if (extpos != std::string::npos) + { + std::string_view ext = name.substr(extpos); + for (const auto& blockedext : filter->blockedextensions) + { + if (ext == blockedext) + return true; + } + } + return false; +} + +static bool IsBlockedFolder(LumpFilterInfo* filter, const std::string_view& name) +{ + size_t start = 0; + while (true) + { + size_t end = std::min(name.find_first_of("/\\", start), name.size()); + std::string_view folder = name.substr(start, end - start); + + if (folder.empty()) + break; + + for (const auto& blockedfolder : filter->blockedfolders) + { + if (folder == blockedfolder) + return true; + } + + if (end == name.size()) + break; + + start = end + 1; + } + return false; +} + //========================================================================== // // FResourceFile :: PostProcessArchive @@ -365,14 +405,13 @@ void FResourceFile::PostProcessArchive(LumpFilterInfo *filter) { for (uint32_t i = 0; i < NumLumps; i++) { - std::string name = Entries[i].FileName; - for (auto& pattern : filter->blockednames) + // Note: this used wildcards::match before. That was super slow in debug builds in particular. + // Do not change it back to wildcards, please. + + std::string_view name = Entries[i].FileName; + if (IsBlockedExt(filter, name) || IsBlockedFolder(filter, name)) { - if (wildcards::match(name, pattern)) - { - Entries[i].FileName = ""; - continue; - } + Entries[i].FileName = ""; } } } diff --git a/src/common/filesystem/source/wildcards.hpp b/src/common/filesystem/source/wildcards.hpp deleted file mode 100644 index 9b8e4eac6..000000000 --- a/src/common/filesystem/source/wildcards.hpp +++ /dev/null @@ -1,1833 +0,0 @@ -// THIS FILE HAS BEEN GENERATED AUTOMATICALLY. DO NOT EDIT DIRECTLY. -// Generated: 2019-03-08 09:59:35.958950200 -// Copyright Tomas Zeman 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef WILDCARDS_HPP -#define WILDCARDS_HPP -#define WILDCARDS_VERSION_MAJOR 1 -#define WILDCARDS_VERSION_MINOR 5 -#define WILDCARDS_VERSION_PATCH 0 -#ifndef WILDCARDS_CARDS_HPP -#define WILDCARDS_CARDS_HPP -#include -namespace wildcards -{ -template -struct cards -{ -constexpr cards(T a, T s, T e) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{false}, -alt_enabled{false} -{ -} -constexpr cards(T a, T s, T e, T so, T sc, T sn, T ao, T ac, T ar) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{true}, -set_open{std::move(so)}, -set_close{std::move(sc)}, -set_not{std::move(sn)}, -alt_enabled{true}, -alt_open{std::move(ao)}, -alt_close{std::move(ac)}, -alt_or{std::move(ar)} -{ -} -T anything; -T single; -T escape; -bool set_enabled; -T set_open; -T set_close; -T set_not; -bool alt_enabled; -T alt_open; -T alt_close; -T alt_or; -}; -enum class cards_type -{ -standard, -extended -}; -template <> -struct cards -{ -constexpr cards(cards_type type = cards_type::extended) -: set_enabled{type == cards_type::extended}, alt_enabled{type == cards_type::extended} -{ -} -constexpr cards(char a, char s, char e) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{false}, -alt_enabled{false} -{ -} -constexpr cards(char a, char s, char e, char so, char sc, char sn, char ao, char ac, char ar) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{true}, -set_open{std::move(so)}, -set_close{std::move(sc)}, -set_not{std::move(sn)}, -alt_enabled{true}, -alt_open{std::move(ao)}, -alt_close{std::move(ac)}, -alt_or{std::move(ar)} -{ -} -char anything{'*'}; -char single{'?'}; -char escape{'\\'}; -bool set_enabled{true}; -char set_open{'['}; -char set_close{']'}; -char set_not{'!'}; -bool alt_enabled{true}; -char alt_open{'('}; -char alt_close{')'}; -char alt_or{'|'}; -}; -template <> -struct cards -{ -constexpr cards(cards_type type = cards_type::extended) -: set_enabled{type == cards_type::extended}, alt_enabled{type == cards_type::extended} -{ -} -constexpr cards(char16_t a, char16_t s, char16_t e) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{false}, -alt_enabled{false} -{ -} -constexpr cards(char16_t a, char16_t s, char16_t e, char16_t so, char16_t sc, char16_t sn, -char16_t ao, char16_t ac, char16_t ar) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{true}, -set_open{std::move(so)}, -set_close{std::move(sc)}, -set_not{std::move(sn)}, -alt_enabled{true}, -alt_open{std::move(ao)}, -alt_close{std::move(ac)}, -alt_or{std::move(ar)} -{ -} -char16_t anything{u'*'}; -char16_t single{u'?'}; -char16_t escape{u'\\'}; -bool set_enabled{true}; -char16_t set_open{u'['}; -char16_t set_close{u']'}; -char16_t set_not{u'!'}; -bool alt_enabled{true}; -char16_t alt_open{u'('}; -char16_t alt_close{u')'}; -char16_t alt_or{u'|'}; -}; -template <> -struct cards -{ -constexpr cards(cards_type type = cards_type::extended) -: set_enabled{type == cards_type::extended}, alt_enabled{type == cards_type::extended} -{ -} -constexpr cards(char32_t a, char32_t s, char32_t e) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{false}, -alt_enabled{false} -{ -} -constexpr cards(char32_t a, char32_t s, char32_t e, char32_t so, char32_t sc, char32_t sn, -char32_t ao, char32_t ac, char32_t ar) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{true}, -set_open{std::move(so)}, -set_close{std::move(sc)}, -set_not{std::move(sn)}, -alt_enabled{true}, -alt_open{std::move(ao)}, -alt_close{std::move(ac)}, -alt_or{std::move(ar)} -{ -} -char32_t anything{U'*'}; -char32_t single{U'?'}; -char32_t escape{U'\\'}; -bool set_enabled{true}; -char32_t set_open{U'['}; -char32_t set_close{U']'}; -char32_t set_not{U'!'}; -bool alt_enabled{true}; -char32_t alt_open{U'('}; -char32_t alt_close{U')'}; -char32_t alt_or{U'|'}; -}; -template <> -struct cards -{ -constexpr cards(cards_type type = cards_type::extended) -: set_enabled{type == cards_type::extended}, alt_enabled{type == cards_type::extended} -{ -} -constexpr cards(wchar_t a, wchar_t s, wchar_t e) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{false}, -alt_enabled{false} -{ -} -constexpr cards(wchar_t a, wchar_t s, wchar_t e, wchar_t so, wchar_t sc, wchar_t sn, wchar_t ao, -wchar_t ac, wchar_t ar) -: anything{std::move(a)}, -single{std::move(s)}, -escape{std::move(e)}, -set_enabled{true}, -set_open{std::move(so)}, -set_close{std::move(sc)}, -set_not{std::move(sn)}, -alt_enabled{true}, -alt_open{std::move(ao)}, -alt_close{std::move(ac)}, -alt_or{std::move(ar)} -{ -} -wchar_t anything{L'*'}; -wchar_t single{L'?'}; -wchar_t escape{L'\\'}; -bool set_enabled{true}; -wchar_t set_open{L'['}; -wchar_t set_close{L']'}; -wchar_t set_not{L'!'}; -bool alt_enabled{true}; -wchar_t alt_open{L'('}; -wchar_t alt_close{L')'}; -wchar_t alt_or{L'|'}; -}; -template -constexpr cards make_cards(T&& a, T&& s, T&& e) -{ -return {std::forward(a), std::forward(s), std::forward(e)}; -} -template -constexpr cards make_cards(T&& a, T&& s, T&& e, T&& so, T&& sc, T&& sn, T&& ao, T&& ac, T&& ar) -{ -return {std::forward(a), std::forward(s), std::forward(e), -std::forward(so), std::forward(sc), std::forward(sn), -std::forward(ao), std::forward(ac), std::forward(ar)}; -} -} -#endif -#ifndef WILDCARDS_MATCH_HPP -#define WILDCARDS_MATCH_HPP -#include -#include -#include -#ifndef CONFIG_HPP -#define CONFIG_HPP -#ifndef QUICKCPPLIB_HAS_FEATURE_H -#define QUICKCPPLIB_HAS_FEATURE_H -#if __cplusplus >= 201103L -#if !defined(__cpp_alias_templates) -#define __cpp_alias_templates 190000 -#endif -#if !defined(__cpp_attributes) -#define __cpp_attributes 190000 -#endif -#if !defined(__cpp_constexpr) -#if __cplusplus >= 201402L -#define __cpp_constexpr 201304 -#else -#define __cpp_constexpr 190000 -#endif -#endif -#if !defined(__cpp_decltype) -#define __cpp_decltype 190000 -#endif -#if !defined(__cpp_delegating_constructors) -#define __cpp_delegating_constructors 190000 -#endif -#if !defined(__cpp_explicit_conversion) -#define __cpp_explicit_conversion 190000 -#endif -#if !defined(__cpp_inheriting_constructors) -#define __cpp_inheriting_constructors 190000 -#endif -#if !defined(__cpp_initializer_lists) -#define __cpp_initializer_lists 190000 -#endif -#if !defined(__cpp_lambdas) -#define __cpp_lambdas 190000 -#endif -#if !defined(__cpp_nsdmi) -#define __cpp_nsdmi 190000 -#endif -#if !defined(__cpp_range_based_for) -#define __cpp_range_based_for 190000 -#endif -#if !defined(__cpp_raw_strings) -#define __cpp_raw_strings 190000 -#endif -#if !defined(__cpp_ref_qualifiers) -#define __cpp_ref_qualifiers 190000 -#endif -#if !defined(__cpp_rvalue_references) -#define __cpp_rvalue_references 190000 -#endif -#if !defined(__cpp_static_assert) -#define __cpp_static_assert 190000 -#endif -#if !defined(__cpp_unicode_characters) -#define __cpp_unicode_characters 190000 -#endif -#if !defined(__cpp_unicode_literals) -#define __cpp_unicode_literals 190000 -#endif -#if !defined(__cpp_user_defined_literals) -#define __cpp_user_defined_literals 190000 -#endif -#if !defined(__cpp_variadic_templates) -#define __cpp_variadic_templates 190000 -#endif -#endif -#if __cplusplus >= 201402L -#if !defined(__cpp_aggregate_nsdmi) -#define __cpp_aggregate_nsdmi 190000 -#endif -#if !defined(__cpp_binary_literals) -#define __cpp_binary_literals 190000 -#endif -#if !defined(__cpp_decltype_auto) -#define __cpp_decltype_auto 190000 -#endif -#if !defined(__cpp_generic_lambdas) -#define __cpp_generic_lambdas 190000 -#endif -#if !defined(__cpp_init_captures) -#define __cpp_init_captures 190000 -#endif -#if !defined(__cpp_return_type_deduction) -#define __cpp_return_type_deduction 190000 -#endif -#if !defined(__cpp_sized_deallocation) -#define __cpp_sized_deallocation 190000 -#endif -#if !defined(__cpp_variable_templates) -#define __cpp_variable_templates 190000 -#endif -#endif -#if defined(_MSC_VER) && !defined(__clang__) -#if !defined(__cpp_exceptions) && defined(_CPPUNWIND) -#define __cpp_exceptions 190000 -#endif -#if !defined(__cpp_rtti) && defined(_CPPRTTI) -#define __cpp_rtti 190000 -#endif -#if !defined(__cpp_alias_templates) && _MSC_VER >= 1800 -#define __cpp_alias_templates 190000 -#endif -#if !defined(__cpp_attributes) -#define __cpp_attributes 190000 -#endif -#if !defined(__cpp_constexpr) && _MSC_FULL_VER >= 190023506 -#define __cpp_constexpr 190000 -#endif -#if !defined(__cpp_decltype) && _MSC_VER >= 1600 -#define __cpp_decltype 190000 -#endif -#if !defined(__cpp_delegating_constructors) && _MSC_VER >= 1800 -#define __cpp_delegating_constructors 190000 -#endif -#if !defined(__cpp_explicit_conversion) && _MSC_VER >= 1800 -#define __cpp_explicit_conversion 190000 -#endif -#if !defined(__cpp_inheriting_constructors) && _MSC_VER >= 1900 -#define __cpp_inheriting_constructors 190000 -#endif -#if !defined(__cpp_initializer_lists) && _MSC_VER >= 1900 -#define __cpp_initializer_lists 190000 -#endif -#if !defined(__cpp_lambdas) && _MSC_VER >= 1600 -#define __cpp_lambdas 190000 -#endif -#if !defined(__cpp_nsdmi) && _MSC_VER >= 1900 -#define __cpp_nsdmi 190000 -#endif -#if !defined(__cpp_range_based_for) && _MSC_VER >= 1700 -#define __cpp_range_based_for 190000 -#endif -#if !defined(__cpp_raw_strings) && _MSC_VER >= 1800 -#define __cpp_raw_strings 190000 -#endif -#if !defined(__cpp_ref_qualifiers) && _MSC_VER >= 1900 -#define __cpp_ref_qualifiers 190000 -#endif -#if !defined(__cpp_rvalue_references) && _MSC_VER >= 1600 -#define __cpp_rvalue_references 190000 -#endif -#if !defined(__cpp_static_assert) && _MSC_VER >= 1600 -#define __cpp_static_assert 190000 -#endif -#if !defined(__cpp_user_defined_literals) && _MSC_VER >= 1900 -#define __cpp_user_defined_literals 190000 -#endif -#if !defined(__cpp_variadic_templates) && _MSC_VER >= 1800 -#define __cpp_variadic_templates 190000 -#endif -#if !defined(__cpp_binary_literals) && _MSC_VER >= 1900 -#define __cpp_binary_literals 190000 -#endif -#if !defined(__cpp_decltype_auto) && _MSC_VER >= 1900 -#define __cpp_decltype_auto 190000 -#endif -#if !defined(__cpp_generic_lambdas) && _MSC_VER >= 1900 -#define __cpp_generic_lambdas 190000 -#endif -#if !defined(__cpp_init_captures) && _MSC_VER >= 1900 -#define __cpp_init_captures 190000 -#endif -#if !defined(__cpp_return_type_deduction) && _MSC_VER >= 1900 -#define __cpp_return_type_deduction 190000 -#endif -#if !defined(__cpp_sized_deallocation) && _MSC_VER >= 1900 -#define __cpp_sized_deallocation 190000 -#endif -#if !defined(__cpp_variable_templates) && _MSC_FULL_VER >= 190023506 -#define __cpp_variable_templates 190000 -#endif -#endif -#if(defined(__GNUC__) && !defined(__clang__)) -#define QUICKCPPLIB_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#if !defined(__cpp_exceptions) && defined(__EXCEPTIONS) -#define __cpp_exceptions 190000 -#endif -#if !defined(__cpp_rtti) && defined(__GXX_RTTI) -#define __cpp_rtti 190000 -#endif -#if defined(__GXX_EXPERIMENTAL_CXX0X__) -#if !defined(__cpp_alias_templates) && (QUICKCPPLIB_GCC >= 40700) -#define __cpp_alias_templates 190000 -#endif -#if !defined(__cpp_attributes) && (QUICKCPPLIB_GCC >= 40800) -#define __cpp_attributes 190000 -#endif -#if !defined(__cpp_constexpr) && (QUICKCPPLIB_GCC >= 40600) -#define __cpp_constexpr 190000 -#endif -#if !defined(__cpp_decltype) && (QUICKCPPLIB_GCC >= 40300) -#define __cpp_decltype 190000 -#endif -#if !defined(__cpp_delegating_constructors) && (QUICKCPPLIB_GCC >= 40700) -#define __cpp_delegating_constructors 190000 -#endif -#if !defined(__cpp_explicit_conversion) && (QUICKCPPLIB_GCC >= 40500) -#define __cpp_explicit_conversion 190000 -#endif -#if !defined(__cpp_inheriting_constructors) && (QUICKCPPLIB_GCC >= 40800) -#define __cpp_inheriting_constructors 190000 -#endif -#if !defined(__cpp_initializer_lists) && (QUICKCPPLIB_GCC >= 40800) -#define __cpp_initializer_lists 190000 -#endif -#if !defined(__cpp_lambdas) && (QUICKCPPLIB_GCC >= 40500) -#define __cpp_lambdas 190000 -#endif -#if !defined(__cpp_nsdmi) && (QUICKCPPLIB_GCC >= 40700) -#define __cpp_nsdmi 190000 -#endif -#if !defined(__cpp_range_based_for) && (QUICKCPPLIB_GCC >= 40600) -#define __cpp_range_based_for 190000 -#endif -#if !defined(__cpp_raw_strings) && (QUICKCPPLIB_GCC >= 40500) -#define __cpp_raw_strings 190000 -#endif -#if !defined(__cpp_ref_qualifiers) && (QUICKCPPLIB_GCC >= 40801) -#define __cpp_ref_qualifiers 190000 -#endif -#if !defined(__cpp_rvalue_references) && defined(__cpp_rvalue_reference) -#define __cpp_rvalue_references __cpp_rvalue_reference -#endif -#if !defined(__cpp_static_assert) && (QUICKCPPLIB_GCC >= 40300) -#define __cpp_static_assert 190000 -#endif -#if !defined(__cpp_unicode_characters) && (QUICKCPPLIB_GCC >= 40500) -#define __cpp_unicode_characters 190000 -#endif -#if !defined(__cpp_unicode_literals) && (QUICKCPPLIB_GCC >= 40500) -#define __cpp_unicode_literals 190000 -#endif -#if !defined(__cpp_user_defined_literals) && (QUICKCPPLIB_GCC >= 40700) -#define __cpp_user_defined_literals 190000 -#endif -#if !defined(__cpp_variadic_templates) && (QUICKCPPLIB_GCC >= 40400) -#define __cpp_variadic_templates 190000 -#endif -#endif -#endif -#if defined(__clang__) -#define QUICKCPPLIB_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) -#if !defined(__cpp_exceptions) && (defined(__EXCEPTIONS) || defined(_CPPUNWIND)) -#define __cpp_exceptions 190000 -#endif -#if !defined(__cpp_rtti) && (defined(__GXX_RTTI) || defined(_CPPRTTI)) -#define __cpp_rtti 190000 -#endif -#if defined(__GXX_EXPERIMENTAL_CXX0X__) -#if !defined(__cpp_alias_templates) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_alias_templates 190000 -#endif -#if !defined(__cpp_attributes) && (QUICKCPPLIB_CLANG >= 30300) -#define __cpp_attributes 190000 -#endif -#if !defined(__cpp_constexpr) && (QUICKCPPLIB_CLANG >= 30100) -#define __cpp_constexpr 190000 -#endif -#if !defined(__cpp_decltype) && (QUICKCPPLIB_CLANG >= 20900) -#define __cpp_decltype 190000 -#endif -#if !defined(__cpp_delegating_constructors) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_delegating_constructors 190000 -#endif -#if !defined(__cpp_explicit_conversion) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_explicit_conversion 190000 -#endif -#if !defined(__cpp_inheriting_constructors) && (QUICKCPPLIB_CLANG >= 30300) -#define __cpp_inheriting_constructors 190000 -#endif -#if !defined(__cpp_initializer_lists) && (QUICKCPPLIB_CLANG >= 30100) -#define __cpp_initializer_lists 190000 -#endif -#if !defined(__cpp_lambdas) && (QUICKCPPLIB_CLANG >= 30100) -#define __cpp_lambdas 190000 -#endif -#if !defined(__cpp_nsdmi) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_nsdmi 190000 -#endif -#if !defined(__cpp_range_based_for) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_range_based_for 190000 -#endif -#if !defined(__cpp_raw_strings) && defined(__cpp_raw_string_literals) -#define __cpp_raw_strings __cpp_raw_string_literals -#endif -#if !defined(__cpp_raw_strings) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_raw_strings 190000 -#endif -#if !defined(__cpp_ref_qualifiers) && (QUICKCPPLIB_CLANG >= 20900) -#define __cpp_ref_qualifiers 190000 -#endif -#if !defined(__cpp_rvalue_references) && defined(__cpp_rvalue_reference) -#define __cpp_rvalue_references __cpp_rvalue_reference -#endif -#if !defined(__cpp_rvalue_references) && (QUICKCPPLIB_CLANG >= 20900) -#define __cpp_rvalue_references 190000 -#endif -#if !defined(__cpp_static_assert) && (QUICKCPPLIB_CLANG >= 20900) -#define __cpp_static_assert 190000 -#endif -#if !defined(__cpp_unicode_characters) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_unicode_characters 190000 -#endif -#if !defined(__cpp_unicode_literals) && (QUICKCPPLIB_CLANG >= 30000) -#define __cpp_unicode_literals 190000 -#endif -#if !defined(__cpp_user_defined_literals) && defined(__cpp_user_literals) -#define __cpp_user_defined_literals __cpp_user_literals -#endif -#if !defined(__cpp_user_defined_literals) && (QUICKCPPLIB_CLANG >= 30100) -#define __cpp_user_defined_literals 190000 -#endif -#if !defined(__cpp_variadic_templates) && (QUICKCPPLIB_CLANG >= 20900) -#define __cpp_variadic_templates 190000 -#endif -#endif -#endif -#endif -#define cfg_HAS_CONSTEXPR14 (__cpp_constexpr >= 201304) -#if cfg_HAS_CONSTEXPR14 -#define cfg_constexpr14 constexpr -#else -#define cfg_constexpr14 -#endif -#if cfg_HAS_CONSTEXPR14 && defined(__clang__) -#define cfg_HAS_FULL_FEATURED_CONSTEXPR14 1 -#else -#define cfg_HAS_FULL_FEATURED_CONSTEXPR14 1 -#endif -#endif -#ifndef CX_FUNCTIONAL_HPP -#define CX_FUNCTIONAL_HPP -#include -namespace cx -{ -template -struct less -{ -constexpr auto operator()(const T& lhs, const T& rhs) const -> decltype(lhs < rhs) -{ -return lhs < rhs; -} -}; -template <> -struct less -{ -template -constexpr auto operator()(T&& lhs, U&& rhs) const --> decltype(std::forward(lhs) < std::forward(rhs)) -{ -return std::forward(lhs) < std::forward(rhs); -} -}; -template -struct equal_to -{ -constexpr auto operator()(const T& lhs, const T& rhs) const -> decltype(lhs == rhs) -{ -return lhs == rhs; -} -}; -template <> -struct equal_to -{ -template -constexpr auto operator()(T&& lhs, U&& rhs) const --> decltype(std::forward(lhs) == std::forward(rhs)) -{ -return std::forward(lhs) == std::forward(rhs); -} -}; -} -#endif -#ifndef CX_ITERATOR_HPP -#define CX_ITERATOR_HPP -#include -#include -namespace cx -{ -template -constexpr It next(It it) -{ -return it + 1; -} -template -constexpr It prev(It it) -{ -return it - 1; -} -template -constexpr auto size(const C& c) -> decltype(c.size()) -{ -return c.size(); -} -template -constexpr std::size_t size(const T (&)[N]) -{ -return N; -} -template -constexpr auto empty(const C& c) -> decltype(c.empty()) -{ -return c.empty(); -} -template -constexpr bool empty(const T (&)[N]) -{ -return false; -} -template -constexpr bool empty(std::initializer_list il) -{ -return il.size() == 0; -} -template -constexpr auto begin(const C& c) -> decltype(c.begin()) -{ -return c.begin(); -} -template -constexpr auto begin(C& c) -> decltype(c.begin()) -{ -return c.begin(); -} -template -constexpr T* begin(T (&array)[N]) -{ -return &array[0]; -} -template -constexpr const E* begin(std::initializer_list il) -{ -return il.begin(); -} -template -constexpr auto cbegin(const C& c) -> decltype(cx::begin(c)) -{ -return cx::begin(c); -} -template -constexpr auto end(const C& c) -> decltype(c.end()) -{ -return c.end(); -} -template -constexpr auto end(C& c) -> decltype(c.end()) -{ -return c.end(); -} -template -constexpr T* end(T (&array)[N]) -{ -return &array[N]; -} -template -constexpr const E* end(std::initializer_list il) -{ -return il.end(); -} -template -constexpr auto cend(const C& c) -> decltype(cx::end(c)) -{ -return cx::end(c); -} -} -#endif -#ifndef WILDCARDS_UTILITY_HPP -#define WILDCARDS_UTILITY_HPP -#include -#include -namespace wildcards -{ -template -struct const_iterator -{ -using type = typename std::remove_cv< -typename std::remove_reference()))>::type>::type; -}; -template -using const_iterator_t = typename const_iterator::type; -template -struct iterator -{ -using type = typename std::remove_cv< -typename std::remove_reference()))>::type>::type; -}; -template -using iterator_t = typename iterator::type; -template -struct iterated_item -{ -using type = typename std::remove_cv< -typename std::remove_reference())>::type>::type; -}; -template -using iterated_item_t = typename iterated_item::type; -template -struct container_item -{ -using type = typename std::remove_cv< -typename std::remove_reference()))>::type>::type; -}; -template -using container_item_t = typename container_item::type; -} -#endif -namespace wildcards -{ -template -struct full_match_result -{ -bool res; -SequenceIterator s, send, s1; -PatternIterator p, pend, p1; -constexpr operator bool() const -{ -return res; -} -}; -namespace detail -{ -template -struct match_result -{ -bool res; -SequenceIterator s; -PatternIterator p; -constexpr operator bool() const -{ -return res; -} -}; -template -constexpr match_result make_match_result(bool res, -SequenceIterator s, -PatternIterator p) -{ -return {std::move(res), std::move(s), std::move(p)}; -} -template -constexpr full_match_result make_full_match_result( -SequenceIterator s, SequenceIterator send, PatternIterator p, PatternIterator pend, -match_result mr) -{ -return {std::move(mr.res), std::move(s), std::move(send), std::move(mr.s), -std::move(p), std::move(pend), std::move(mr.p)}; -} -#if !cfg_HAS_FULL_FEATURED_CONSTEXPR14 -constexpr bool throw_invalid_argument(const char* what_arg) -{ -return what_arg == nullptr ? false : throw std::invalid_argument(what_arg); -} -template -constexpr T throw_invalid_argument(T t, const char* what_arg) -{ -return what_arg == nullptr ? t : throw std::invalid_argument(what_arg); -} -constexpr bool throw_logic_error(const char* what_arg) -{ -return what_arg == nullptr ? false : throw std::logic_error(what_arg); -} -template -constexpr T throw_logic_error(T t, const char* what_arg) -{ -return what_arg == nullptr ? t : throw std::logic_error(what_arg); -} -#endif -enum class is_set_state -{ -open, -not_or_first, -first, -next -}; -template -constexpr bool is_set( -PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -is_set_state state = is_set_state::open) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.set_enabled) -{ -return false; -} -while (p != pend) -{ -switch (state) -{ -case is_set_state::open: -if (*p != c.set_open) -{ -return false; -} -state = is_set_state::not_or_first; -break; -case is_set_state::not_or_first: -if (*p == c.set_not) -{ -state = is_set_state::first; -} -else -{ -state = is_set_state::next; -} -break; -case is_set_state::first: -state = is_set_state::next; -break; -case is_set_state::next: -if (*p == c.set_close) -{ -return true; -} -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -"The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -return false; -#else -return c.set_enabled && p != pend && -(state == is_set_state::open -? *p == c.set_open && is_set(cx::next(p), pend, c, is_set_state::not_or_first) -: -state == is_set_state::not_or_first -? *p == c.set_not ? is_set(cx::next(p), pend, c, is_set_state::first) -: is_set(cx::next(p), pend, c, is_set_state::next) -: state == is_set_state::first -? is_set(cx::next(p), pend, c, is_set_state::next) -: state == is_set_state::next -? *p == c.set_close || -is_set(cx::next(p), pend, c, is_set_state::next) -: throw std::logic_error("The program execution should never end up " -"here throwing this exception")); -#endif -} -enum class set_end_state -{ -open, -not_or_first, -first, -next -}; -template -constexpr PatternIterator set_end( -PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -set_end_state state = set_end_state::open) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.set_enabled) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The use of sets is disabled"); -#else -return throw_invalid_argument(p, "The use of sets is disabled"); -#endif -} -while (p != pend) -{ -switch (state) -{ -case set_end_state::open: -if (*p != c.set_open) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid set"); -#else -return throw_invalid_argument(p, "The given pattern is not a valid set"); -#endif -} -state = set_end_state::not_or_first; -break; -case set_end_state::not_or_first: -if (*p == c.set_not) -{ -state = set_end_state::first; -} -else -{ -state = set_end_state::next; -} -break; -case set_end_state::first: -state = set_end_state::next; -break; -case set_end_state::next: -if (*p == c.set_close) -{ -return cx::next(p); -} -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -p, "The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid set"); -#else -return throw_invalid_argument(p, "The given pattern is not a valid set"); -#endif -#else -return !c.set_enabled -? throw std::invalid_argument("The use of sets is disabled") -: p == pend -? throw std::invalid_argument("The given pattern is not a valid set") -: -state == set_end_state::open -? *p == c.set_open -? set_end(cx::next(p), pend, c, set_end_state::not_or_first) -: throw std::invalid_argument("The given pattern is not a valid set") -: -state == set_end_state::not_or_first -? *p == c.set_not ? set_end(cx::next(p), pend, c, set_end_state::first) -: set_end(cx::next(p), pend, c, set_end_state::next) -: state == set_end_state::first -? set_end(cx::next(p), pend, c, set_end_state::next) -: state == set_end_state::next -? *p == c.set_close -? cx::next(p) -: set_end(cx::next(p), pend, c, set_end_state::next) -: throw std::logic_error( -"The program execution should never end up " -"here throwing this exception"); -#endif -} -enum class match_set_state -{ -open, -not_or_first_in, -first_out, -next_in, -next_out -}; -template > -constexpr match_result match_set( -SequenceIterator s, SequenceIterator send, PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -const EqualTo& equal_to = EqualTo(), match_set_state state = match_set_state::open) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.set_enabled) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The use of sets is disabled"); -#else -return throw_invalid_argument(make_match_result(false, s, p), "The use of sets is disabled"); -#endif -} -while (p != pend) -{ -switch (state) -{ -case match_set_state::open: -if (*p != c.set_open) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid set"); -#else -return throw_invalid_argument(make_match_result(false, s, p), -"The given pattern is not a valid set"); -#endif -} -state = match_set_state::not_or_first_in; -break; -case match_set_state::not_or_first_in: -if (*p == c.set_not) -{ -state = match_set_state::first_out; -} -else -{ -if (s == send) -{ -return make_match_result(false, s, p); -} -if (equal_to(*s, *p)) -{ -return make_match_result(true, s, p); -} -state = match_set_state::next_in; -} -break; -case match_set_state::first_out: -if (s == send || equal_to(*s, *p)) -{ -return make_match_result(false, s, p); -} -state = match_set_state::next_out; -break; -case match_set_state::next_in: -if (*p == c.set_close || s == send) -{ -return make_match_result(false, s, p); -} -if (equal_to(*s, *p)) -{ -return make_match_result(true, s, p); -} -break; -case match_set_state::next_out: -if (*p == c.set_close) -{ -return make_match_result(true, s, p); -} -if (s == send || equal_to(*s, *p)) -{ -return make_match_result(false, s, p); -} -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -make_match_result(false, s, p), -"The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid set"); -#else -return throw_invalid_argument(make_match_result(false, s, p), -"The given pattern is not a valid set"); -#endif -#else -return !c.set_enabled -? throw std::invalid_argument("The use of sets is disabled") -: p == pend -? throw std::invalid_argument("The given pattern is not a valid set") -: state == match_set_state::open -? *p == c.set_open -? match_set(s, send, cx::next(p), pend, c, equal_to, -match_set_state::not_or_first_in) -: -throw std::invalid_argument("The given pattern is not a valid set") -: -state == match_set_state::not_or_first_in -? *p == c.set_not -? match_set(s, send, cx::next(p), pend, c, equal_to, -match_set_state::first_out) -: -s == send ? make_match_result(false, s, p) -: equal_to(*s, *p) -? make_match_result(true, s, p) -: match_set(s, send, cx::next(p), pend, c, -equal_to, match_set_state::next_in) -: -state == match_set_state::first_out -? s == send || equal_to(*s, *p) -? make_match_result(false, s, p) -: match_set(s, send, cx::next(p), pend, c, equal_to, -match_set_state::next_out) -: -state == match_set_state::next_in -? *p == c.set_close || s == send -? make_match_result(false, s, p) -: equal_to(*s, *p) ? make_match_result(true, s, p) -: match_set(s, send, cx::next(p), -pend, c, equal_to, state) -: -state == match_set_state::next_out -? *p == c.set_close -? make_match_result(true, s, p) -: s == send || equal_to(*s, *p) -? make_match_result(false, s, p) -: match_set(s, send, cx::next(p), pend, c, -equal_to, state) -: throw std::logic_error( -"The program execution should never end up " -"here " -"throwing this exception"); -#endif -} -enum class is_alt_state -{ -open, -next, -escape -}; -template -constexpr bool is_alt( -PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -is_alt_state state = is_alt_state::open, int depth = 0) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.alt_enabled) -{ -return false; -} -while (p != pend) -{ -switch (state) -{ -case is_alt_state::open: -if (*p != c.alt_open) -{ -return false; -} -state = is_alt_state::next; -++depth; -break; -case is_alt_state::next: -if (*p == c.escape) -{ -state = is_alt_state::escape; -} -else if (c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, is_set_state::not_or_first)) -{ -p = cx::prev(set_end(cx::next(p), pend, c, set_end_state::not_or_first)); -} -else if (*p == c.alt_open) -{ -++depth; -} -else if (*p == c.alt_close) -{ ---depth; -if (depth == 0) -{ -return true; -} -} -break; -case is_alt_state::escape: -state = is_alt_state::next; -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -p, "The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -return false; -#else -return c.alt_enabled && p != pend && -(state == is_alt_state::open -? *p == c.alt_open && is_alt(cx::next(p), pend, c, is_alt_state::next, depth + 1) -: state == is_alt_state::next -? *p == c.escape -? is_alt(cx::next(p), pend, c, is_alt_state::escape, depth) -: c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, is_set_state::not_or_first) -? is_alt(set_end(cx::next(p), pend, c, set_end_state::not_or_first), -pend, c, state, depth) -: *p == c.alt_open -? is_alt(cx::next(p), pend, c, state, depth + 1) -: *p == c.alt_close -? depth == 1 || -is_alt(cx::next(p), pend, c, state, depth - 1) -: is_alt(cx::next(p), pend, c, state, depth) -: -state == is_alt_state::escape -? is_alt(cx::next(p), pend, c, is_alt_state::next, depth) -: throw std::logic_error( -"The program execution should never end up here throwing this " -"exception")); -#endif -} -enum class alt_end_state -{ -open, -next, -escape -}; -template -constexpr PatternIterator alt_end( -PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -alt_end_state state = alt_end_state::open, int depth = 0) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.alt_enabled) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The use of alternatives is disabled"); -#else -return throw_invalid_argument(p, "The use of alternatives is disabled"); -#endif -} -while (p != pend) -{ -switch (state) -{ -case alt_end_state::open: -if (*p != c.alt_open) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid alternative"); -#else -return throw_invalid_argument(p, "The given pattern is not a valid alternative"); -#endif -} -state = alt_end_state::next; -++depth; -break; -case alt_end_state::next: -if (*p == c.escape) -{ -state = alt_end_state::escape; -} -else if (c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, is_set_state::not_or_first)) -{ -p = cx::prev(set_end(cx::next(p), pend, c, set_end_state::not_or_first)); -} -else if (*p == c.alt_open) -{ -++depth; -} -else if (*p == c.alt_close) -{ ---depth; -if (depth == 0) -{ -return cx::next(p); -} -} -break; -case alt_end_state::escape: -state = alt_end_state::next; -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -p, "The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid alternative"); -#else -return throw_invalid_argument(p, "The given pattern is not a valid alternative"); -#endif -#else -return !c.alt_enabled -? throw std::invalid_argument("The use of alternatives is disabled") -: p == pend -? throw std::invalid_argument("The given pattern is not a valid alternative") -: state == alt_end_state::open -? *p == c.alt_open -? alt_end(cx::next(p), pend, c, alt_end_state::next, depth + 1) -: throw std::invalid_argument( -"The given pattern is not a valid alternative") -: state == alt_end_state::next -? *p == c.escape -? alt_end(cx::next(p), pend, c, alt_end_state::escape, depth) -: c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, -is_set_state::not_or_first) -? alt_end(set_end(cx::next(p), pend, c, -set_end_state::not_or_first), -pend, c, state, depth) -: *p == c.alt_open -? alt_end(cx::next(p), pend, c, state, depth + 1) -: *p == c.alt_close -? depth == 1 ? cx::next(p) -: alt_end(cx::next(p), pend, c, -state, depth - 1) -: alt_end(cx::next(p), pend, c, state, depth) -: -state == alt_end_state::escape -? alt_end(cx::next(p), pend, c, alt_end_state::next, depth) -: throw std::logic_error( -"The program execution should never end up here throwing " -"this " -"exception"); -#endif -} -enum class alt_sub_end_state -{ -next, -escape -}; -template -constexpr PatternIterator alt_sub_end( -PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -alt_sub_end_state state = alt_sub_end_state::next, int depth = 1) -{ -#if cfg_HAS_CONSTEXPR14 -if (!c.alt_enabled) -{ -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The use of alternatives is disabled"); -#else -return throw_invalid_argument(p, "The use of alternatives is disabled"); -#endif -} -while (p != pend) -{ -switch (state) -{ -case alt_sub_end_state::next: -if (*p == c.escape) -{ -state = alt_sub_end_state::escape; -} -else if (c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, is_set_state::not_or_first)) -{ -p = cx::prev(set_end(cx::next(p), pend, c, set_end_state::not_or_first)); -} -else if (*p == c.alt_open) -{ -++depth; -} -else if (*p == c.alt_close) -{ ---depth; -if (depth == 0) -{ -return p; -} -} -else if (*p == c.alt_or) -{ -if (depth == 1) -{ -return p; -} -} -break; -case alt_sub_end_state::escape: -state = alt_sub_end_state::next; -break; -default: -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::logic_error( -"The program execution should never end up here throwing this exception"); -#else -return throw_logic_error( -p, "The program execution should never end up here throwing this exception"); -#endif -} -p = cx::next(p); -} -#if cfg_HAS_FULL_FEATURED_CONSTEXPR14 -throw std::invalid_argument("The given pattern is not a valid alternative"); -#else -return throw_invalid_argument(p, "The given pattern is not a valid alternative"); -#endif -#else -return !c.alt_enabled -? throw std::invalid_argument("The use of alternatives is disabled") -: p == pend -? throw std::invalid_argument("The given pattern is not a valid alternative") -: state == alt_sub_end_state::next -? *p == c.escape -? alt_sub_end(cx::next(p), pend, c, alt_sub_end_state::escape, depth) -: c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, is_set_state::not_or_first) -? alt_sub_end(set_end(cx::next(p), pend, c, -set_end_state::not_or_first), -pend, c, state, depth) -: *p == c.alt_open -? alt_sub_end(cx::next(p), pend, c, state, depth + 1) -: *p == c.alt_close -? depth == 1 ? p : alt_sub_end(cx::next(p), pend, -c, state, depth - 1) -: *p == c.alt_or -? depth == 1 ? p -: alt_sub_end(cx::next(p), pend, -c, state, depth) -: alt_sub_end(cx::next(p), pend, c, state, -depth) -: -state == alt_sub_end_state::escape -? alt_sub_end(cx::next(p), pend, c, alt_sub_end_state::next, depth) -: throw std::logic_error( -"The program execution should never end up here throwing " -"this " -"exception"); -#endif -} -template > -constexpr match_result match( -SequenceIterator s, SequenceIterator send, PatternIterator p, PatternIterator pend, -const cards>& c = cards>(), -const EqualTo& equal_to = EqualTo(), bool partial = false, bool escape = false); -template > -constexpr match_result match_alt( -SequenceIterator s, SequenceIterator send, PatternIterator p1, PatternIterator p1end, -PatternIterator p2, PatternIterator p2end, -const cards>& c = cards>(), -const EqualTo& equal_to = EqualTo(), bool partial = false) -{ -#if cfg_HAS_CONSTEXPR14 -auto result1 = match(s, send, p1, p1end, c, equal_to, true); -if (result1) -{ -auto result2 = match(result1.s, send, p2, p2end, c, equal_to, partial); -if (result2) -{ -return result2; -} -} -p1 = cx::next(p1end); -if (p1 == p2) -{ -return make_match_result(false, s, p1end); -} -return match_alt(s, send, p1, alt_sub_end(p1, p2, c), p2, p2end, c, equal_to, partial); -#else -return match(s, send, p1, p1end, c, equal_to, true) && -match(match(s, send, p1, p1end, c, equal_to, true).s, send, p2, p2end, c, equal_to, -partial) -? match(match(s, send, p1, p1end, c, equal_to, true).s, send, p2, p2end, c, equal_to, -partial) -: cx::next(p1end) == p2 -? make_match_result(false, s, p1end) -: match_alt(s, send, cx::next(p1end), alt_sub_end(cx::next(p1end), p2, c), p2, -p2end, c, equal_to, partial); -#endif -} -template -constexpr match_result match( -SequenceIterator s, SequenceIterator send, PatternIterator p, PatternIterator pend, -const cards>& c, const EqualTo& equal_to, bool partial, -bool escape) -{ -#if cfg_HAS_CONSTEXPR14 -if (p == pend) -{ -return make_match_result(partial || s == send, s, p); -} -if (escape) -{ -if (s == send || !equal_to(*s, *p)) -{ -return make_match_result(false, s, p); -} -return match(cx::next(s), send, cx::next(p), pend, c, equal_to, partial); -} -if (*p == c.anything) -{ -auto result = match(s, send, cx::next(p), pend, c, equal_to, partial); -if (result) -{ -return result; -} -if (s == send) -{ -return make_match_result(false, s, p); -} -return match(cx::next(s), send, p, pend, c, equal_to, partial); -} -if (*p == c.single) -{ -if (s == send) -{ -return make_match_result(false, s, p); -} -return match(cx::next(s), send, cx::next(p), pend, c, equal_to, partial); -} -if (*p == c.escape) -{ -return match(s, send, cx::next(p), pend, c, equal_to, partial, true); -} -if (c.set_enabled && *p == c.set_open && is_set(cx::next(p), pend, c, is_set_state::not_or_first)) -{ -auto result = -match_set(s, send, cx::next(p), pend, c, equal_to, match_set_state::not_or_first_in); -if (!result) -{ -return result; -} -return match(cx::next(s), send, set_end(cx::next(p), pend, c, set_end_state::not_or_first), -pend, c, equal_to, partial); -} -if (c.alt_enabled && *p == c.alt_open && is_alt(cx::next(p), pend, c, is_alt_state::next, 1)) -{ -auto p_alt_end = alt_end(cx::next(p), pend, c, alt_end_state::next, 1); -return match_alt(s, send, cx::next(p), alt_sub_end(cx::next(p), p_alt_end, c), p_alt_end, pend, -c, equal_to, partial); -} -if (s == send || !equal_to(*s, *p)) -{ -return make_match_result(false, s, p); -} -return match(cx::next(s), send, cx::next(p), pend, c, equal_to, partial); -#else -return p == pend -? make_match_result(partial || s == send, s, p) -: escape -? s == send || !equal_to(*s, *p) -? make_match_result(false, s, p) -: match(cx::next(s), send, cx::next(p), pend, c, equal_to, partial) -: *p == c.anything -? match(s, send, cx::next(p), pend, c, equal_to, partial) -? match(s, send, cx::next(p), pend, c, equal_to, partial) -: s == send ? make_match_result(false, s, p) -: match(cx::next(s), send, p, pend, c, equal_to, partial) -: *p == c.single -? s == send ? make_match_result(false, s, p) -: match(cx::next(s), send, cx::next(p), pend, c, -equal_to, partial) -: *p == c.escape -? match(s, send, cx::next(p), pend, c, equal_to, partial, true) -: c.set_enabled && *p == c.set_open && -is_set(cx::next(p), pend, c, -is_set_state::not_or_first) -? !match_set(s, send, cx::next(p), pend, c, equal_to, -match_set_state::not_or_first_in) -? match_set(s, send, cx::next(p), pend, c, -equal_to, -match_set_state::not_or_first_in) -: match(cx::next(s), send, -set_end(cx::next(p), pend, c, -set_end_state::not_or_first), -pend, c, equal_to, partial) -: c.alt_enabled && *p == c.alt_open && -is_alt(cx::next(p), pend, c, -is_alt_state::next, 1) -? match_alt( -s, send, cx::next(p), -alt_sub_end(cx::next(p), -alt_end(cx::next(p), pend, c, -alt_end_state::next, 1), -c), -alt_end(cx::next(p), pend, c, -alt_end_state::next, 1), -pend, c, equal_to, partial) -: s == send || !equal_to(*s, *p) -? make_match_result(false, s, p) -: match(cx::next(s), send, cx::next(p), pend, -c, equal_to, partial); -#endif -} -} -template > -constexpr full_match_result, const_iterator_t> match( -Sequence&& sequence, Pattern&& pattern, -const cards>& c = cards>(), -const EqualTo& equal_to = EqualTo()) -{ -return detail::make_full_match_result( -cx::cbegin(sequence), cx::cend(sequence), cx::cbegin(pattern), cx::cend(pattern), -detail::match(cx::cbegin(sequence), cx::cend(std::forward(sequence)), -cx::cbegin(pattern), cx::cend(std::forward(pattern)), c, equal_to)); -} -template , -typename = typename std::enable_if::value>::type> -constexpr full_match_result, const_iterator_t> match( -Sequence&& sequence, Pattern&& pattern, const EqualTo& equal_to) -{ -return match(std::forward(sequence), std::forward(pattern), -cards>(), equal_to); -} -} -#endif -#ifndef WILDCARDS_MATCHER_HPP -#define WILDCARDS_MATCHER_HPP -#include -#include -#include -#ifndef CX_STRING_VIEW_HPP -#define CX_STRING_VIEW_HPP -#include -#include -#ifndef CX_ALGORITHM_HPP -#define CX_ALGORITHM_HPP -namespace cx -{ -template -constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) -{ -#if cfg_HAS_CONSTEXPR14 -while (first1 != last1 && first2 != last2 && *first1 == *first2) -{ -++first1, ++first2; -} -return first1 == last1 && first2 == last2; -#else -return first1 != last1 && first2 != last2 && *first1 == *first2 -? equal(first1 + 1, last1, first2 + 1, last2) -: first1 == last1 && first2 == last2; -#endif -} -} -#endif -namespace cx -{ -template -class basic_string_view -{ -public: -using value_type = T; -constexpr basic_string_view() = default; -template -constexpr basic_string_view(const T (&str)[N]) : data_{&str[0]}, size_{N - 1} -{ -} -constexpr basic_string_view(const T* str, std::size_t s) : data_{str}, size_{s} -{ -} -constexpr const T* data() const -{ -return data_; -} -constexpr std::size_t size() const -{ -return size_; -} -constexpr bool empty() const -{ -return size() == 0; -} -constexpr const T* begin() const -{ -return data_; -} -constexpr const T* cbegin() const -{ -return begin(); -} -constexpr const T* end() const -{ -return data_ + size_; -} -constexpr const T* cend() const -{ -return end(); -} -private: -const T* data_{nullptr}; -std::size_t size_{0}; -}; -template -constexpr bool operator==(const basic_string_view& lhs, const basic_string_view& rhs) -{ -return equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); -} -template -constexpr bool operator!=(const basic_string_view& lhs, const basic_string_view& rhs) -{ -return !(lhs == rhs); -} -template -std::basic_ostream& operator<<(std::basic_ostream& o, const basic_string_view& s) -{ -o << s.data(); -return o; -} -template -constexpr basic_string_view make_string_view(const T (&str)[N]) -{ -return {str, N - 1}; -} -template -constexpr basic_string_view make_string_view(const T* str, std::size_t s) -{ -return {str, s}; -} -using string_view = basic_string_view; -using u16string_view = basic_string_view; -using u32string_view = basic_string_view; -using wstring_view = basic_string_view; -namespace literals -{ -constexpr string_view operator"" _sv(const char* str, std::size_t s) -{ -return {str, s}; -} -constexpr u16string_view operator"" _sv(const char16_t* str, std::size_t s) -{ -return {str, s}; -} -constexpr u32string_view operator"" _sv(const char32_t* str, std::size_t s) -{ -return {str, s}; -} -constexpr wstring_view operator"" _sv(const wchar_t* str, std::size_t s) -{ -return {str, s}; -} -} -} -#endif -namespace wildcards -{ -template > -class matcher -{ -public: -constexpr explicit matcher(Pattern&& pattern, const cards>& c = -cards>(), -const EqualTo& equal_to = EqualTo()) -: p_{cx::cbegin(pattern)}, -pend_{cx::cend(std::forward(pattern))}, -c_{c}, -equal_to_{equal_to} -{ -} -constexpr matcher(Pattern&& pattern, const EqualTo& equal_to) -: p_{cx::cbegin(pattern)}, -pend_{cx::cend(std::forward(pattern))}, -c_{cards>()}, -equal_to_{equal_to} -{ -} -template -constexpr full_match_result, const_iterator_t> matches( -Sequence&& sequence) const -{ -return detail::make_full_match_result( -cx::cbegin(sequence), cx::cend(sequence), p_, pend_, -detail::match(cx::cbegin(sequence), cx::cend(std::forward(sequence)), p_, pend_, -c_, equal_to_)); -} -private: -const_iterator_t p_; -const_iterator_t pend_; -cards> c_; -EqualTo equal_to_; -}; -template > -constexpr matcher make_matcher( -Pattern&& pattern, -const cards>& c = cards>(), -const EqualTo& equal_to = EqualTo()) -{ -return matcher{std::forward(pattern), c, equal_to}; -} -template , -typename = typename std::enable_if::value>::type> -constexpr matcher make_matcher(Pattern&& pattern, const EqualTo& equal_to) -{ -return make_matcher(std::forward(pattern), cards>(), equal_to); -} -namespace literals -{ -constexpr auto operator"" _wc(const char* str, std::size_t s) --> decltype(make_matcher(cx::make_string_view(str, s + 1))) -{ -return make_matcher(cx::make_string_view(str, s + 1)); -} -constexpr auto operator"" _wc(const char16_t* str, std::size_t s) --> decltype(make_matcher(cx::make_string_view(str, s + 1))) -{ -return make_matcher(cx::make_string_view(str, s + 1)); -} -constexpr auto operator"" _wc(const char32_t* str, std::size_t s) --> decltype(make_matcher(cx::make_string_view(str, s + 1))) -{ -return make_matcher(cx::make_string_view(str, s + 1)); -} -constexpr auto operator"" _wc(const wchar_t* str, std::size_t s) --> decltype(make_matcher(cx::make_string_view(str, s + 1))) -{ -return make_matcher(cx::make_string_view(str, s + 1)); -} -} -} -#endif -#endif diff --git a/src/d_main.cpp b/src/d_main.cpp index ff161c624..2b5e52edf 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1986,7 +1986,8 @@ void GetReserved(LumpFilterInfo& lfi) lfi.reservedFolders = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/", "materials/", "models/", "fonts/", "brightmaps/" }; lfi.requiredPrefixes = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "complvl", "terrain", "maps/" }; - lfi.blockednames = { "*.bat", "*.exe", "__macosx/*", "*/__macosx/*" }; + lfi.blockedextensions = { ".bat", ".exe" }; + lfi.blockedfolders = { "__macosx" }; } static FString CheckGameInfo(std::vector & pwads)