diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61dbb63e7..32eb2d4ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,6 +135,41 @@ jobs: - name: Test run: ../../../b2 toolset=$TOOLSET define=CI_SUPPRESS_KNOWN_ISSUES define=SLOW_COMPILER working-directory: ../boost-root/libs/regex/test + ubuntu-jammy-clang-18-modules: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: '0' + - uses: mstachniuk/ci-skip@v1 + with: + commit-filter: '[skip ci];[ci skip];[CI SKIP];[SKIP CI];***CI SKIP***;***SKIP CI***;[windows];[Windows];[WINDOWS];[apple];[Apple];[APPLE]' + commit-filter-separator: ';' + fail-fast: true + - name: Grab install script + run: wget https://apt.llvm.org/llvm.sh && chmod u+x llvm.sh + - name: Install clang 18 packages + run: sudo ./llvm.sh 18 && clang++-18 --version + - name: Checkout main boost + run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root + - name: Update tools/boostdep + run: git submodule update --init tools/boostdep + working-directory: ../boost-root + - name: Copy files + run: cp -r $GITHUB_WORKSPACE/* libs/regex + working-directory: ../boost-root + - name: Install deps + run: python tools/boostdep/depinst/depinst.py -I example -g "--jobs 3" regex + working-directory: ../boost-root + - name: Bootstrap + run: ./bootstrap.sh + working-directory: ../boost-root + - name: Generate headers + run: ./b2 headers + working-directory: ../boost-root + - name: Test + run: CXX=clang++-18 LIBRARIES="-licuuc -licudata -licui18n" ./test_clang.sh + working-directory: ../boost-root/libs/regex/test/module macos: runs-on: macos-latest strategy: @@ -339,6 +374,9 @@ jobs: commit-filter: '[skip ci];[ci skip];[CI SKIP];[SKIP CI];***CI SKIP***;***SKIP CI***;[apple];[Apple];[APPLE];[linux];[Linux];[LINUX]' commit-filter-separator: ';' fail-fast: true + - uses: TheMrMilchmann/setup-msvc-dev@v3 + with: + arch: x64 - name: Checkout main boost run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - name: Update tools/boostdep @@ -365,6 +403,9 @@ jobs: - name: Test run: ..\..\..\b2 --hash %ARGS% working-directory: ../boost-root/libs/regex/test + - name: Module Test + run: msvc_test.bat + working-directory: ../boost-root/libs/regex/test/module ubuntu-cmake-install: runs-on: ubuntu-20.04 strategy: diff --git a/doc/html/boost_regex/install.html b/doc/html/boost_regex/install.html index 8cb6a3381..cbfdf01ae 100644 --- a/doc/html/boost_regex/install.html +++ b/doc/html/boost_regex/install.html @@ -7,7 +7,7 @@ - + @@ -21,7 +21,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -109,7 +109,7 @@


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_regex/intro.html b/doc/html/boost_regex/intro.html index eb27e5346..96ad6eb76 100644 --- a/doc/html/boost_regex/intro.html +++ b/doc/html/boost_regex/intro.html @@ -6,7 +6,7 @@ - + @@ -21,7 +21,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -206,7 +206,7 @@


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_regex/modules.html b/doc/html/boost_regex/modules.html new file mode 100644 index 000000000..69538fe6b --- /dev/null +++ b/doc/html/boost_regex/modules.html @@ -0,0 +1,108 @@ + + + +Module Support (Experimental) + + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ This library has experimental support for C++ modules (C++20 or later), currently + the support is experimental not least because at the time of writing (2025) + build tools have yet to catch up with module support. +

+

+ In order to use this library as a module you simply add a: +

+
import boost.regex;
+
+

+ to your code. +

+

+ Before that you must first build the module, which consists of these steps: +

+
    +
  • + Depending on your compiler, you may need to build the standard library + module, and place the standard module somewhere that your compiler can + find it. +
  • +
  • + Build libs/regex/module/regex.cxx into the boost.regex module, and + place the module definition file somewhere that your compiler can find + it. +
  • +
  • + Build all the source files in libs/regex/module + (including regex.cxx) into a library, and place the result somewhere your + linker can find it. +
  • +
+

+ Visual studio users can simplify all of the above into one step, by placing + everything in libs/regex/module + into a static library project, and then adding the /interface command line option to the regex.cxx + source file. +

+

+ Known limitations: +

+
    +
  • + As of the start of 2025, only very recent versions of clang and msvc are + supported. GCC is definitely not supported. +
  • +
  • + The regex library must always be consumed via import + boost.regex; + and you can never mix this with #includes + <boost/regex.hpp>. +
  • +
  • + Ideally the standard library should always be used via import + std and not via #includes: more + recent compilers are mostly making this work, but are still very fragile. +
  • +
  • + The regex version imported, is always the "standalone" version + which includes no other Boost headers. +
  • +
+

+ Finally... there are some build and test scripts in libs/regex/test/module + for msvc and clang. +

+
+ +
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/index.html b/doc/html/index.html index 639afd79c..d082acfc0 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -50,6 +50,7 @@
Algorithm Tuning
Building and Installing the Library
+
Module Support (Experimental)
Introduction and Overview
Unicode and Boost.Regex
Understanding Marked Sub-Expressions diff --git a/doc/modules.qbk b/doc/modules.qbk new file mode 100644 index 000000000..6358c23b0 --- /dev/null +++ b/doc/modules.qbk @@ -0,0 +1,40 @@ +[/ + Copyright 2024 John Maddock. + 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). +] + +[section:modules Module Support (Experimental)] + +This library has experimental support for C++ modules (C++20 or later), currently the support is experimental +not least because at the time of writing (2025) build tools have yet to catch up with module support. + +In order to use this library as a module you simply add a: + +``` +import boost.regex; +``` + +to your code. + +Before that you must first build the module, which consists of these steps: + +* Depending on your compiler, you may need to build the standard library module, and place the standard module somewhere that your compiler can find it. +* Build `libs/regex/module/regex.cxx` into the boost.regex module, and place the module definition file somewhere that your compiler can find it. +* Build all the source files in `libs/regex/module` (including regex.cxx) into a library, and place the result somewhere your linker can find it. + +Visual studio users can simplify all of the above into one step, by placing everything in `libs/regex/module` into a static library project, and then adding the `/interface` +command line option to the regex.cxx source file. + +Known limitations: + +* As of the start of 2025, only very recent versions of clang and msvc are supported. GCC is definitely not supported. +* The regex library must always be consumed via `import boost.regex;` and you can never mix this with `#includes `. +* Ideally the standard library should always be used via `import std` and not via #includes: more recent compilers are mostly making this work, but are still very fragile. +* The regex version imported, is always the "standalone" version which includes no other Boost headers. + +Finally... there are some build and test scripts in `libs/regex/test/module` for msvc and clang. + +[endsect] + diff --git a/doc/regex.qbk b/doc/regex.qbk index bc3d8103d..ebad5c2e9 100644 --- a/doc/regex.qbk +++ b/doc/regex.qbk @@ -51,6 +51,7 @@ PDF version of this manual is also available]. [include configuration.qbk] [include install.qbk] +[include modules.qbk] [include introduction.qbk] [include unicode.qbk] [include captures.qbk] diff --git a/include/boost/regex/concepts.hpp b/include/boost/regex/concepts.hpp index 5e6ebc01d..f2a1a1d7e 100644 --- a/include/boost/regex/concepts.hpp +++ b/include/boost/regex/concepts.hpp @@ -24,7 +24,7 @@ #include #include #include -#ifndef BOOST_TEST_TR1_REGEX +#if !defined(BOOST_TEST_TR1_REGEX) && !defined(BOOST_REGEX_TEST_MODULE) #include #endif #include @@ -37,6 +37,16 @@ #define RW_NS std #endif + + // + // alter this to std::tr1, to test a std implementation: + // +#ifndef BOOST_TEST_TR1_REGEX +namespace global_regex_namespace = ::boost; +#else +namespace global_regex_namespace = ::std::tr1; +#endif + namespace boost{ // @@ -178,15 +188,6 @@ struct regex_traits_architype regex_traits_architype& operator=(const regex_traits_architype&){ return *this; } }; -// -// alter this to std::tr1, to test a std implementation: -// -#ifndef BOOST_TEST_TR1_REGEX -namespace global_regex_namespace = ::boost; -#else -namespace global_regex_namespace = ::std::tr1; -#endif - template struct BitmaskConcept { @@ -273,7 +274,7 @@ template struct regex_traits_computer; template -struct regex_traits_computer< global_regex_namespace::basic_regex > +struct regex_traits_computer< ::boost::basic_regex > { typedef traits type; }; diff --git a/include/boost/regex/config.hpp b/include/boost/regex/config.hpp index ea4df9c5f..c2c4fd0f0 100644 --- a/include/boost/regex/config.hpp +++ b/include/boost/regex/config.hpp @@ -29,6 +29,22 @@ #endif #endif +#ifndef BOOST_REGEX_MODULE_EXPORT +#define BOOST_REGEX_MODULE_EXPORT +#define BOOST_REGEX_STATIC_CONST static const +#else +#define BOOST_REGEX_STATIC_CONST inline constexpr +#define BOOST_REGEX_STANDALONE +#endif + +/* + * Borland C++ Fix/error check + * this has to go *before* we include any std lib headers: + */ +#if defined(__BORLANDC__) && !defined(__clang__) +# include +#endif + #ifndef BOOST_REGEX_STANDALONE #include #endif @@ -40,9 +56,13 @@ *************************************************************************/ #ifdef BOOST_REGEX_STANDALONE +#ifndef BOOST_REGEX_AS_MODULE #include # define BOOST_REGEX_ASSERT(x) assert(x) #else +# define BOOST_REGEX_ASSERT(x) do{ if(x == 0) { std::printf("%s:%d Assertion Failed", __FILE__, __LINE__); std::abort(); } }while(0) +#endif +#else #include # define BOOST_REGEX_ASSERT(x) BOOST_ASSERT(x) #endif @@ -284,8 +304,6 @@ * If there are no exceptions then we must report critical-errors * the only way we know how; by terminating. */ -#include - # define BOOST_REGEX_NOEH_ASSERT(x) assert(x); #else /* diff --git a/include/boost/regex/v5/basic_regex.hpp b/include/boost/regex/v5/basic_regex.hpp index b611a5289..311187d54 100644 --- a/include/boost/regex/v5/basic_regex.hpp +++ b/include/boost/regex/v5/basic_regex.hpp @@ -25,10 +25,12 @@ #include #include +#ifndef BOOST_REGEX_AS_MODULE #include #include #include #include +#endif namespace boost{ #ifdef BOOST_REGEX_MSVC @@ -67,7 +69,12 @@ void bubble_down_one(I first, I last) } } -static const int hash_value_mask = 1 << (std::numeric_limits::digits - 1); +#ifndef BOOST_REGEX_AS_MODULE +static +#else +inline +#endif +const int hash_value_mask = 1 << (std::numeric_limits::digits - 1); template inline int hash_value_from_capture_name(Iterator i, Iterator j) @@ -315,7 +322,7 @@ class basic_regex_implementation // represents the compiled // regular expression: // - +BOOST_REGEX_MODULE_EXPORT #ifdef BOOST_REGEX_NO_FWD template > #else @@ -652,22 +659,38 @@ class basic_regex : public regbase // and are designed to provide the strong exception guarantee // (in the event of a throw, the state of the object remains unchanged). // + +namespace detail +{ + template + std::shared_ptr > create_implemenation(const charT* p1, const charT* p2, F f, std::shared_ptr > ptraits) + { + std::shared_ptr > result; + if (!ptraits.get()) + { + result = std::shared_ptr >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation()); + } + else + { + result = std::shared_ptr >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation(ptraits)); + } + result->assign(p1, p2, f); + return result; + } +#ifdef BOOST_REGEX_AS_MODULE + std::shared_ptr::traits_type> > + create_implemenation(const char* p1, const char* p2, basic_regex::flag_type f, std::shared_ptr::traits_type> > ptraits); + std::shared_ptr::traits_type> > + create_implemenation(const wchar_t* p1, const wchar_t* p2, basic_regex::flag_type f, std::shared_ptr::traits_type> > ptraits); +#endif +} + template basic_regex& basic_regex::do_assign(const charT* p1, const charT* p2, flag_type f) { - std::shared_ptr > temp; - if(!m_pimpl.get()) - { - temp = std::shared_ptr >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation()); - } - else - { - temp = std::shared_ptr >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation(m_pimpl->m_ptraits)); - } - temp->assign(p1, p2, f); - temp.swap(m_pimpl); + m_pimpl = detail::create_implemenation(p1, p2, f, m_pimpl.get() ? m_pimpl->m_ptraits : std::shared_ptr >()); return *this; } @@ -683,13 +706,13 @@ typename basic_regex::locale_type basic_regex::im // // non-members: // -template +BOOST_REGEX_MODULE_EXPORT template void swap(basic_regex& e1, basic_regex& e2) { e1.swap(e2); } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_ostream& operator << (std::basic_ostream& os, const basic_regex& e) diff --git a/include/boost/regex/v5/basic_regex_creator.hpp b/include/boost/regex/v5/basic_regex_creator.hpp index d9ae7807f..a8a1a1dca 100644 --- a/include/boost/regex/v5/basic_regex_creator.hpp +++ b/include/boost/regex/v5/basic_regex_creator.hpp @@ -30,8 +30,10 @@ #include +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ @@ -220,8 +222,10 @@ class basic_regex_creator m_icase = static_cast(f & regbase::icase); } } - re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base)); - re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base)); + re_syntax_base* append_state(syntax_element_type t, std::size_t s); + re_syntax_base* append_state(syntax_element_type t) { return append_state(t, sizeof(re_syntax_base)); } + re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s); + re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t) { return insert_state(pos, t, sizeof(re_syntax_base)); } re_literal* append_literal(charT c); re_syntax_base* append_set(const basic_char_set& char_set); re_syntax_base* append_set(const basic_char_set& char_set, std::integral_constant*); diff --git a/include/boost/regex/v5/basic_regex_parser.hpp b/include/boost/regex/v5/basic_regex_parser.hpp index 16e78849d..f3f3a27ea 100644 --- a/include/boost/regex/v5/basic_regex_parser.hpp +++ b/include/boost/regex/v5/basic_regex_parser.hpp @@ -21,10 +21,12 @@ #include +#ifndef BOOST_REGEX_AS_MODULE #include #include #include #include +#endif namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/c_regex_traits.hpp b/include/boost/regex/v5/c_regex_traits.hpp index c22ce35cd..3dbf4d896 100644 --- a/include/boost/regex/v5/c_regex_traits.hpp +++ b/include/boost/regex/v5/c_regex_traits.hpp @@ -19,15 +19,17 @@ #ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED #define BOOST_C_REGEX_TRAITS_HPP_INCLUDED +#ifndef BOOST_REGEX_AS_MODULE +#include +#include +#include +#endif + #include #include #include #include -#include -#include -#include - namespace boost{ namespace BOOST_REGEX_DETAIL_NS { @@ -54,10 +56,10 @@ namespace boost{ } -template +BOOST_REGEX_MODULE_EXPORT template struct c_regex_traits; -template<> +BOOST_REGEX_MODULE_EXPORT template<> struct c_regex_traits { c_regex_traits(){} @@ -102,7 +104,7 @@ struct c_regex_traits }; #ifndef BOOST_NO_WREGEX -template<> +BOOST_REGEX_MODULE_EXPORT template<> struct c_regex_traits { c_regex_traits(){} diff --git a/include/boost/regex/v5/cpp_regex_traits.hpp b/include/boost/regex/v5/cpp_regex_traits.hpp index 26b6f503d..a79f6628a 100644 --- a/include/boost/regex/v5/cpp_regex_traits.hpp +++ b/include/boost/regex/v5/cpp_regex_traits.hpp @@ -20,22 +20,25 @@ #define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED #include + +#ifndef BOOST_REGEX_AS_MODULE #include #include #include +#include +#include +#include +#ifdef BOOST_HAS_THREADS +#include +#endif +#endif #include #include -#ifdef BOOST_HAS_THREADS -#include -#endif #include #include -#include -#include -#include #ifdef BOOST_REGEX_MSVC #pragma warning(push) @@ -47,7 +50,7 @@ namespace boost{ // // forward declaration is needed by some compilers: // -template +BOOST_REGEX_MODULE_EXPORT template class cpp_regex_traits; namespace BOOST_REGEX_DETAIL_NS{ @@ -731,7 +734,7 @@ inline std::shared_ptr > create_cpp } // BOOST_REGEX_DETAIL_NS -template +BOOST_REGEX_MODULE_EXPORT template class cpp_regex_traits { private: diff --git a/include/boost/regex/v5/cregex.hpp b/include/boost/regex/v5/cregex.hpp index f855001e9..f568d3b39 100644 --- a/include/boost/regex/v5/cregex.hpp +++ b/include/boost/regex/v5/cregex.hpp @@ -38,11 +38,13 @@ #endif #endif +#ifndef BOOST_REGEX_AS_MODULE #ifdef __cplusplus #include #else #include #endif +#endif /* include these defs only for POSIX compatablity */ #ifdef __cplusplus diff --git a/include/boost/regex/v5/error_type.hpp b/include/boost/regex/v5/error_type.hpp index afcc71e3d..a3161d287 100644 --- a/include/boost/regex/v5/error_type.hpp +++ b/include/boost/regex/v5/error_type.hpp @@ -26,7 +26,7 @@ namespace boost{ #ifdef __cplusplus namespace regex_constants{ -enum error_type{ +BOOST_REGEX_MODULE_EXPORT enum error_type{ error_ok = 0, /* not used */ error_no_match = 1, /* not used */ diff --git a/include/boost/regex/v5/icu.hpp b/include/boost/regex/v5/icu.hpp index aefd97684..213633aa0 100644 --- a/include/boost/regex/v5/icu.hpp +++ b/include/boost/regex/v5/icu.hpp @@ -19,11 +19,13 @@ #ifndef BOOST_REGEX_ICU_V5_HPP #define BOOST_REGEX_ICU_V5_HPP +#ifndef BOOST_REGEX_AS_MODULE #include #include #include #include #include +#endif #include #include @@ -835,7 +837,7 @@ bool do_regex_match(BidiIterator first, BidiIterator last, } } // namespace BOOST_REGEX_DETAIL_NS -template +BOOST_REGEX_MODULE_EXPORT template inline bool u32regex_match(BidiIterator first, BidiIterator last, match_results& m, const u32regex& e, @@ -843,7 +845,7 @@ inline bool u32regex_match(BidiIterator first, BidiIterator last, { return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const UChar* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const UChar* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -851,7 +853,7 @@ inline bool u32regex_match(const UChar* p, return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast const*>(0)); } #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX) -inline bool u32regex_match(const wchar_t* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const wchar_t* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -859,21 +861,21 @@ inline bool u32regex_match(const wchar_t* p, return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast const*>(0)); } #endif -inline bool u32regex_match(const char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const char* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) { return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const unsigned char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const unsigned char* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) { return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const std::string& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const std::string& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -881,7 +883,7 @@ inline bool u32regex_match(const std::string& s, return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast const*>(0)); } #ifndef BOOST_NO_STD_WSTRING -inline bool u32regex_match(const std::wstring& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const std::wstring& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -889,7 +891,7 @@ inline bool u32regex_match(const std::wstring& s, return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast const*>(0)); } #endif -inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -899,7 +901,7 @@ inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, // // regex_match overloads that do not return what matched: // -template +BOOST_REGEX_MODULE_EXPORT template inline bool u32regex_match(BidiIterator first, BidiIterator last, const u32regex& e, match_flag_type flags = match_default) @@ -907,7 +909,7 @@ inline bool u32regex_match(BidiIterator first, BidiIterator last, match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const UChar* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const UChar* p, const u32regex& e, match_flag_type flags = match_default) { @@ -915,7 +917,7 @@ inline bool u32regex_match(const UChar* p, return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast const*>(0)); } #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX) -inline bool u32regex_match(const wchar_t* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const wchar_t* p, const u32regex& e, match_flag_type flags = match_default) { @@ -923,21 +925,21 @@ inline bool u32regex_match(const wchar_t* p, return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast const*>(0)); } #endif -inline bool u32regex_match(const char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const char* p, const u32regex& e, match_flag_type flags = match_default) { match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const unsigned char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const unsigned char* p, const u32regex& e, match_flag_type flags = match_default) { match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast const*>(0)); } -inline bool u32regex_match(const std::string& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const std::string& s, const u32regex& e, match_flag_type flags = match_default) { @@ -945,7 +947,7 @@ inline bool u32regex_match(const std::string& s, return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast const*>(0)); } #ifndef BOOST_NO_STD_WSTRING -inline bool u32regex_match(const std::wstring& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const std::wstring& s, const u32regex& e, match_flag_type flags = match_default) { @@ -953,7 +955,7 @@ inline bool u32regex_match(const std::wstring& s, return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast const*>(0)); } #endif -inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, match_flag_type flags = match_default) { @@ -1011,7 +1013,7 @@ bool do_regex_search(BidiIterator first, BidiIterator last, } } -template +BOOST_REGEX_MODULE_EXPORT template inline bool u32regex_search(BidiIterator first, BidiIterator last, match_results& m, const u32regex& e, @@ -1019,7 +1021,7 @@ inline bool u32regex_search(BidiIterator first, BidiIterator last, { return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast const*>(0)); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool u32regex_search(BidiIterator first, BidiIterator last, match_results& m, const u32regex& e, @@ -1028,7 +1030,7 @@ inline bool u32regex_search(BidiIterator first, BidiIterator last, { return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, base, static_cast const*>(0)); } -inline bool u32regex_search(const UChar* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const UChar* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -1036,7 +1038,7 @@ inline bool u32regex_search(const UChar* p, return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast const*>(0)); } #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX) -inline bool u32regex_search(const wchar_t* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const wchar_t* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -1044,21 +1046,21 @@ inline bool u32regex_search(const wchar_t* p, return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast const*>(0)); } #endif -inline bool u32regex_search(const char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const char* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) { return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast const*>(0)); } -inline bool u32regex_search(const unsigned char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const unsigned char* p, match_results& m, const u32regex& e, match_flag_type flags = match_default) { return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast const*>(0)); } -inline bool u32regex_search(const std::string& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const std::string& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -1066,7 +1068,7 @@ inline bool u32regex_search(const std::string& s, return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast const*>(0)); } #ifndef BOOST_NO_STD_WSTRING -inline bool u32regex_search(const std::wstring& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const std::wstring& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) @@ -1074,14 +1076,14 @@ inline bool u32regex_search(const std::wstring& s, return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast const*>(0)); } #endif -inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, match_results& m, const u32regex& e, match_flag_type flags = match_default) { return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast const*>(0)); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool u32regex_search(BidiIterator first, BidiIterator last, const u32regex& e, match_flag_type flags = match_default) @@ -1089,7 +1091,7 @@ inline bool u32regex_search(BidiIterator first, BidiIterator last, match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast const*>(0)); } -inline bool u32regex_search(const UChar* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const UChar* p, const u32regex& e, match_flag_type flags = match_default) { @@ -1097,7 +1099,7 @@ inline bool u32regex_search(const UChar* p, return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast const*>(0)); } #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX) -inline bool u32regex_search(const wchar_t* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const wchar_t* p, const u32regex& e, match_flag_type flags = match_default) { @@ -1105,21 +1107,21 @@ inline bool u32regex_search(const wchar_t* p, return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast const*>(0)); } #endif -inline bool u32regex_search(const char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const char* p, const u32regex& e, match_flag_type flags = match_default) { match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast const*>(0)); } -inline bool u32regex_search(const unsigned char* p, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const unsigned char* p, const u32regex& e, match_flag_type flags = match_default) { match_results m; return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast const*>(0)); } -inline bool u32regex_search(const std::string& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const std::string& s, const u32regex& e, match_flag_type flags = match_default) { @@ -1127,7 +1129,7 @@ inline bool u32regex_search(const std::string& s, return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast const*>(0)); } #ifndef BOOST_NO_STD_WSTRING -inline bool u32regex_search(const std::wstring& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const std::wstring& s, const u32regex& e, match_flag_type flags = match_default) { @@ -1135,7 +1137,7 @@ inline bool u32regex_search(const std::wstring& s, return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast const*>(0)); } #endif -inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, +BOOST_REGEX_MODULE_EXPORT inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, match_flag_type flags = match_default) { @@ -1258,7 +1260,7 @@ inline BaseIterator extract_output_base(const utf16_output_iterator +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator u32regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, @@ -1277,7 +1279,7 @@ inline OutputIterator u32regex_replace(OutputIterator out, ); } -template +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator u32regex_replace(OutputIterator out, Iterator first, Iterator last, @@ -1296,7 +1298,7 @@ inline OutputIterator u32regex_replace(OutputIterator out, ); } -template +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator u32regex_replace(OutputIterator out, Iterator first, Iterator last, @@ -1315,7 +1317,7 @@ inline OutputIterator u32regex_replace(OutputIterator out, ); } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_string u32regex_replace(const std::basic_string& s, const u32regex& e, const charT* fmt, @@ -1327,7 +1329,7 @@ std::basic_string u32regex_replace(const std::basic_string& s, return result; } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_string u32regex_replace(const std::basic_string& s, const u32regex& e, const std::basic_string& fmt, diff --git a/include/boost/regex/v5/iterator_category.hpp b/include/boost/regex/v5/iterator_category.hpp index 9bd745781..bb6f638e6 100644 --- a/include/boost/regex/v5/iterator_category.hpp +++ b/include/boost/regex/v5/iterator_category.hpp @@ -21,8 +21,10 @@ #ifndef BOOST_REGEX_ITERATOR_CATEGORY_HPP #define BOOST_REGEX_ITERATOR_CATEGORY_HPP +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ namespace detail{ diff --git a/include/boost/regex/v5/iterator_traits.hpp b/include/boost/regex/v5/iterator_traits.hpp index b25375652..7d3290cc5 100644 --- a/include/boost/regex/v5/iterator_traits.hpp +++ b/include/boost/regex/v5/iterator_traits.hpp @@ -19,7 +19,9 @@ #ifndef BOOST_REGEX_V5_ITERATOR_TRAITS_HPP #define BOOST_REGEX_V5_ITERATOR_TRAITS_HPP +#ifndef BOOST_REGEX_AS_MODULE #include +#endif namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/match_flags.hpp b/include/boost/regex/v5/match_flags.hpp index 6ff236b04..d653d1725 100644 --- a/include/boost/regex/v5/match_flags.hpp +++ b/include/boost/regex/v5/match_flags.hpp @@ -19,9 +19,11 @@ #ifndef BOOST_REGEX_V5_MATCH_FLAGS #define BOOST_REGEX_V5_MATCH_FLAGS +#ifndef BOOST_REGEX_AS_MODULE #ifdef __cplusplus # include #endif +#endif #ifdef __cplusplus namespace boost{ @@ -35,7 +37,7 @@ namespace boost{ #endif #endif -typedef enum _match_flags +BOOST_REGEX_MODULE_EXPORT typedef enum _match_flags { match_default = 0, match_not_bol = 1, /* first is not start of line */ @@ -89,22 +91,22 @@ typedef enum _match_flags } match_flags; -typedef match_flags match_flag_type; +BOOST_REGEX_MODULE_EXPORT typedef match_flags match_flag_type; #ifdef __cplusplus -inline match_flags operator&(match_flags m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags operator&(match_flags m1, match_flags m2) { return static_cast(static_cast(m1) & static_cast(m2)); } -inline match_flags operator|(match_flags m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags operator|(match_flags m1, match_flags m2) { return static_cast(static_cast(m1) | static_cast(m2)); } -inline match_flags operator^(match_flags m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags operator^(match_flags m1, match_flags m2) { return static_cast(static_cast(m1) ^ static_cast(m2)); } -inline match_flags operator~(match_flags m1) +BOOST_REGEX_MODULE_EXPORT inline match_flags operator~(match_flags m1) { return static_cast(~static_cast(m1)); } -inline match_flags& operator&=(match_flags& m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags& operator&=(match_flags& m1, match_flags m2) { m1 = m1&m2; return m1; } -inline match_flags& operator|=(match_flags& m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags& operator|=(match_flags& m1, match_flags m2) { m1 = m1|m2; return m1; } -inline match_flags& operator^=(match_flags& m1, match_flags m2) +BOOST_REGEX_MODULE_EXPORT inline match_flags& operator^=(match_flags& m1, match_flags m2) { m1 = m1^m2; return m1; } #endif @@ -113,36 +115,36 @@ inline match_flags& operator^=(match_flags& m1, match_flags m2) /* * import names into boost for backwards compatibility: */ -using regex_constants::match_flag_type; -using regex_constants::match_default; -using regex_constants::match_not_bol; -using regex_constants::match_not_eol; -using regex_constants::match_not_bob; -using regex_constants::match_not_eob; -using regex_constants::match_not_bow; -using regex_constants::match_not_eow; -using regex_constants::match_not_dot_newline; -using regex_constants::match_not_dot_null; -using regex_constants::match_prev_avail; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_flag_type; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_default; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_bol; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_eol; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_bob; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_eob; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_bow; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_eow; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_dot_newline; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_dot_null; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_prev_avail; /* using regex_constants::match_init; */ -using regex_constants::match_any; -using regex_constants::match_not_null; -using regex_constants::match_continuous; -using regex_constants::match_partial; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_any; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_not_null; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_continuous; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_partial; /*using regex_constants::match_stop; */ -using regex_constants::match_all; -using regex_constants::match_perl; -using regex_constants::match_posix; -using regex_constants::match_nosubs; -using regex_constants::match_extra; -using regex_constants::match_single_line; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_all; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_perl; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_posix; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_nosubs; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_extra; +BOOST_REGEX_MODULE_EXPORT using regex_constants::match_single_line; /*using regex_constants::match_max; */ -using regex_constants::format_all; -using regex_constants::format_sed; -using regex_constants::format_perl; -using regex_constants::format_default; -using regex_constants::format_no_copy; -using regex_constants::format_first_only; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_all; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_sed; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_perl; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_default; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_no_copy; +BOOST_REGEX_MODULE_EXPORT using regex_constants::format_first_only; /*using regex_constants::format_is_if;*/ #ifdef BOOST_REGEX_MSVC diff --git a/include/boost/regex/v5/match_results.hpp b/include/boost/regex/v5/match_results.hpp index 78fbeb335..b10585ca7 100644 --- a/include/boost/regex/v5/match_results.hpp +++ b/include/boost/regex/v5/match_results.hpp @@ -24,8 +24,10 @@ #include #include +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ #ifdef BOOST_REGEX_MSVC @@ -45,7 +47,7 @@ class named_subexpressions; } -template +BOOST_REGEX_MODULE_EXPORT template class match_results { private: @@ -674,13 +676,13 @@ void match_results::maybe_assign(const match_results +BOOST_REGEX_MODULE_EXPORT template void swap(match_results& a, match_results& b) { a.swap(b); } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_ostream& operator << (std::basic_ostream& os, const match_results& s) diff --git a/include/boost/regex/v5/mem_block_cache.hpp b/include/boost/regex/v5/mem_block_cache.hpp index d42e4a32b..18116fb43 100644 --- a/include/boost/regex/v5/mem_block_cache.hpp +++ b/include/boost/regex/v5/mem_block_cache.hpp @@ -19,7 +19,7 @@ #define BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP #include - +#ifndef BOOST_REGEX_AS_MODULE #include #ifdef BOOST_HAS_THREADS #include @@ -32,6 +32,7 @@ #define BOOST_REGEX_ATOMIC_POINTER std::atomic #endif #endif +#endif namespace boost{ diff --git a/include/boost/regex/v5/object_cache.hpp b/include/boost/regex/v5/object_cache.hpp index 6ebef9b34..c9aede144 100644 --- a/include/boost/regex/v5/object_cache.hpp +++ b/include/boost/regex/v5/object_cache.hpp @@ -20,6 +20,7 @@ #define BOOST_REGEX_OBJECT_CACHE_HPP #include +#ifndef BOOST_REGEX_AS_MODULE #include #include #include @@ -28,6 +29,7 @@ #ifdef BOOST_HAS_THREADS #include #endif +#endif namespace boost{ diff --git a/include/boost/regex/v5/pattern_except.hpp b/include/boost/regex/v5/pattern_except.hpp index d71a32b7b..e01201039 100644 --- a/include/boost/regex/v5/pattern_except.hpp +++ b/include/boost/regex/v5/pattern_except.hpp @@ -23,8 +23,10 @@ #include #endif +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif #include #include @@ -37,7 +39,7 @@ namespace boost{ #pragma warning(disable : 26812 4459) #endif #endif -class regex_error : public std::runtime_error +BOOST_REGEX_MODULE_EXPORT class regex_error : public std::runtime_error { public: explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0) @@ -72,8 +74,8 @@ class regex_error : public std::runtime_error std::ptrdiff_t m_position; }; -typedef regex_error bad_pattern; -typedef regex_error bad_expression; +BOOST_REGEX_MODULE_EXPORT typedef regex_error bad_pattern; +BOOST_REGEX_MODULE_EXPORT typedef regex_error bad_expression; namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/perl_matcher.hpp b/include/boost/regex/v5/perl_matcher.hpp index 207daedd8..8e600dba4 100644 --- a/include/boost/regex/v5/perl_matcher.hpp +++ b/include/boost/regex/v5/perl_matcher.hpp @@ -19,11 +19,13 @@ #include #include +#ifndef BOOST_REGEX_AS_MODULE #ifndef BOOST_REGEX_STANDALONE #include #endif #include +#endif #ifdef BOOST_REGEX_MSVC # pragma warning(push) @@ -578,6 +580,33 @@ class perl_matcher #endif }; +template +inline bool factory_match(Matcher& m) +{ + return m.match(); +} +template +inline bool factory_find(Matcher& m) +{ + return m.find(); +} + +#ifdef BOOST_REGEX_AS_MODULE +bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m); +bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m); +bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m); + +bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m); +bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m); +bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m); +bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m); +#endif + } // namespace BOOST_REGEX_DETAIL_NS #ifdef BOOST_REGEX_MSVC diff --git a/include/boost/regex/v5/regbase.hpp b/include/boost/regex/v5/regbase.hpp index 5cefb36b4..b9c32b40f 100644 --- a/include/boost/regex/v5/regbase.hpp +++ b/include/boost/regex/v5/regbase.hpp @@ -112,7 +112,7 @@ class regbase // namespace regex_constants{ - enum flag_type_ + BOOST_REGEX_MODULE_EXPORT enum flag_type_ { no_except = ::boost::regbase::no_except, @@ -148,7 +148,7 @@ namespace regex_constants{ JavaScript = normal, JScript = normal }; - typedef ::boost::regbase::flag_type syntax_option_type; + BOOST_REGEX_MODULE_EXPORT typedef ::boost::regbase::flag_type syntax_option_type; } // namespace regex_constants diff --git a/include/boost/regex/v5/regex.hpp b/include/boost/regex/v5/regex.hpp index eb6dc7282..bd5244ee7 100644 --- a/include/boost/regex/v5/regex.hpp +++ b/include/boost/regex/v5/regex.hpp @@ -46,17 +46,17 @@ namespace boost{ #ifdef BOOST_REGEX_NO_FWD -typedef basic_regex > regex; +BOOST_REGEX_MODULE_EXPORT typedef basic_regex > regex; #ifndef BOOST_NO_WREGEX -typedef basic_regex > wregex; +BOOST_REGEX_MODULE_EXPORT typedef basic_regex > wregex; #endif #endif -typedef match_results cmatch; -typedef match_results smatch; +BOOST_REGEX_MODULE_EXPORT typedef match_results cmatch; +BOOST_REGEX_MODULE_EXPORT typedef match_results smatch; #ifndef BOOST_NO_WREGEX -typedef match_results wcmatch; -typedef match_results wsmatch; +BOOST_REGEX_MODULE_EXPORT typedef match_results wcmatch; +BOOST_REGEX_MODULE_EXPORT typedef match_results wsmatch; #endif } // namespace boost diff --git a/include/boost/regex/v5/regex_format.hpp b/include/boost/regex/v5/regex_format.hpp index 31bbfee48..afd9d915a 100644 --- a/include/boost/regex/v5/regex_format.hpp +++ b/include/boost/regex/v5/regex_format.hpp @@ -24,16 +24,17 @@ #include #include #include - +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ // // Forward declaration: // - template >::allocator_type > +BOOST_REGEX_MODULE_EXPORT template >::allocator_type > class match_results; namespace BOOST_REGEX_DETAIL_NS{ @@ -1099,7 +1100,7 @@ struct compute_functor_type } // namespace BOOST_REGEX_DETAIL_NS -template +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator regex_format(OutputIterator out, const match_results& m, Functor fmt, @@ -1109,7 +1110,7 @@ inline OutputIterator regex_format(OutputIterator out, return m.format(out, fmt, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::char_type> regex_format(const match_results& m, Functor fmt, match_flag_type flags = format_all) diff --git a/include/boost/regex/v5/regex_fwd.hpp b/include/boost/regex/v5/regex_fwd.hpp index 3076b069a..4f202a417 100644 --- a/include/boost/regex/v5/regex_fwd.hpp +++ b/include/boost/regex/v5/regex_fwd.hpp @@ -36,30 +36,30 @@ namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template class cpp_regex_traits; -template +BOOST_REGEX_MODULE_EXPORT template struct c_regex_traits; -template +BOOST_REGEX_MODULE_EXPORT template class w32_regex_traits; #ifdef BOOST_REGEX_USE_WIN32_LOCALE -template > +BOOST_REGEX_MODULE_EXPORT template > struct regex_traits; #elif defined(BOOST_REGEX_USE_CPP_LOCALE) -template > +BOOST_REGEX_MODULE_EXPORT template > struct regex_traits; #else -template > +BOOST_REGEX_MODULE_EXPORT template > struct regex_traits; #endif -template > +BOOST_REGEX_MODULE_EXPORT template > class basic_regex; -typedef basic_regex > regex; +BOOST_REGEX_MODULE_EXPORT typedef basic_regex > regex; #ifndef BOOST_NO_WREGEX -typedef basic_regex > wregex; +BOOST_REGEX_MODULE_EXPORT typedef basic_regex > wregex; #endif } // namespace boost diff --git a/include/boost/regex/v5/regex_grep.hpp b/include/boost/regex/v5/regex_grep.hpp index 63f750d5b..4ae6a1779 100644 --- a/include/boost/regex/v5/regex_grep.hpp +++ b/include/boost/regex/v5/regex_grep.hpp @@ -30,7 +30,7 @@ namespace boost{ // regex_grep: // find all non-overlapping matches within the sequence first last: // -template +BOOST_REGEX_MODULE_EXPORT template inline unsigned int regex_grep(Predicate foo, BidiIterator first, BidiIterator last, @@ -45,7 +45,7 @@ inline unsigned int regex_grep(Predicate foo, match_results m; BOOST_REGEX_DETAIL_NS::perl_matcher matcher(first, last, m, e, flags, first); unsigned int count = 0; - while(matcher.find()) + while(BOOST_REGEX_DETAIL_NS::factory_find(matcher)) { ++count; if(0 == foo(m)) @@ -60,7 +60,7 @@ inline unsigned int regex_grep(Predicate foo, // a non-NULL one at the same position: match_results m2(m); matcher.setf(match_not_null | match_continuous); - if(matcher.find()) + if(BOOST_REGEX_DETAIL_NS::factory_find(matcher)) { ++count; if(0 == foo(m)) @@ -80,7 +80,7 @@ inline unsigned int regex_grep(Predicate foo, // // regex_grep convenience interfaces: // -template +BOOST_REGEX_MODULE_EXPORT template inline unsigned int regex_grep(Predicate foo, const charT* str, const basic_regex& e, match_flag_type flags = match_default) @@ -88,7 +88,7 @@ inline unsigned int regex_grep(Predicate foo, const charT* str, return regex_grep(foo, str, str + traits::length(str), e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline unsigned int regex_grep(Predicate foo, const std::basic_string& s, const basic_regex& e, match_flag_type flags = match_default) diff --git a/include/boost/regex/v5/regex_iterator.hpp b/include/boost/regex/v5/regex_iterator.hpp index 17a20ac3a..25a75e550 100644 --- a/include/boost/regex/v5/regex_iterator.hpp +++ b/include/boost/regex/v5/regex_iterator.hpp @@ -21,8 +21,9 @@ #include #include - +#ifndef BOOST_REGEX_AS_MODULE #include +#endif namespace boost{ @@ -75,7 +76,7 @@ class regex_iterator_implementation regex_iterator_implementation& operator=(const regex_iterator_implementation&); }; -template ::value_type, class traits = regex_traits > class regex_iterator @@ -151,20 +152,20 @@ class regex_iterator } }; -typedef regex_iterator cregex_iterator; -typedef regex_iterator sregex_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_iterator cregex_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_iterator sregex_iterator; #ifndef BOOST_NO_WREGEX -typedef regex_iterator wcregex_iterator; -typedef regex_iterator wsregex_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_iterator wcregex_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_iterator wsregex_iterator; #endif // make_regex_iterator: -template +BOOST_REGEX_MODULE_EXPORT template inline regex_iterator make_regex_iterator(const charT* p, const basic_regex& e, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_iterator(p, p+traits::length(p), e, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_iterator::const_iterator, charT, traits> make_regex_iterator(const std::basic_string& p, const basic_regex& e, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_iterator::const_iterator, charT, traits>(p.begin(), p.end(), e, m); diff --git a/include/boost/regex/v5/regex_match.hpp b/include/boost/regex/v5/regex_match.hpp index c2f818145..f70a6e62b 100644 --- a/include/boost/regex/v5/regex_match.hpp +++ b/include/boost/regex/v5/regex_match.hpp @@ -32,16 +32,16 @@ namespace boost{ // returns true if the specified regular expression matches // the whole of the input. Fills in what matched in m. // -template +BOOST_REGEX_MODULE_EXPORT template bool regex_match(BidiIterator first, BidiIterator last, match_results& m, const basic_regex& e, match_flag_type flags = match_default) { BOOST_REGEX_DETAIL_NS::perl_matcher matcher(first, last, m, e, flags, first); - return matcher.match(); + return BOOST_REGEX_DETAIL_NS::factory_match(matcher); } -template +BOOST_REGEX_MODULE_EXPORT template bool regex_match(iterator first, iterator last, const basic_regex& e, match_flag_type flags = match_default) @@ -52,7 +52,7 @@ bool regex_match(iterator first, iterator last, // // query_match convenience interfaces: // -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_match(const charT* str, match_results& m, const basic_regex& e, @@ -61,7 +61,7 @@ inline bool regex_match(const charT* str, return regex_match(str, str + traits::length(str), m, e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_match(const std::basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, @@ -69,7 +69,7 @@ inline bool regex_match(const std::basic_string& s, { return regex_match(s.begin(), s.end(), m, e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_match(const charT* str, const basic_regex& e, match_flag_type flags = match_default) @@ -78,7 +78,7 @@ inline bool regex_match(const charT* str, return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_match(const std::basic_string& s, const basic_regex& e, match_flag_type flags = match_default) diff --git a/include/boost/regex/v5/regex_merge.hpp b/include/boost/regex/v5/regex_merge.hpp index a5103c53e..ba9ac21c2 100644 --- a/include/boost/regex/v5/regex_merge.hpp +++ b/include/boost/regex/v5/regex_merge.hpp @@ -24,7 +24,7 @@ namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator regex_merge(OutputIterator out, Iterator first, Iterator last, @@ -35,7 +35,7 @@ inline OutputIterator regex_merge(OutputIterator out, return regex_replace(out, first, last, e, fmt, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline OutputIterator regex_merge(OutputIterator out, Iterator first, Iterator last, @@ -46,7 +46,7 @@ inline OutputIterator regex_merge(OutputIterator out, return regex_merge(out, first, last, e, fmt.c_str(), flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string regex_merge(const std::basic_string& s, const basic_regex& e, const charT* fmt, @@ -55,7 +55,7 @@ inline std::basic_string regex_merge(const std::basic_string& s, return regex_replace(s, e, fmt, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string regex_merge(const std::basic_string& s, const basic_regex& e, const std::basic_string& fmt, diff --git a/include/boost/regex/v5/regex_raw_buffer.hpp b/include/boost/regex/v5/regex_raw_buffer.hpp index 732955a25..b3b8bb98b 100644 --- a/include/boost/regex/v5/regex_raw_buffer.hpp +++ b/include/boost/regex/v5/regex_raw_buffer.hpp @@ -25,9 +25,11 @@ #include #endif +#ifndef BOOST_REGEX_AS_MODULE #include #include #include +#endif namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/regex_replace.hpp b/include/boost/regex/v5/regex_replace.hpp index 6cdaee82a..4c2e993f4 100644 --- a/include/boost/regex/v5/regex_replace.hpp +++ b/include/boost/regex/v5/regex_replace.hpp @@ -28,7 +28,7 @@ namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, @@ -62,7 +62,7 @@ OutputIterator regex_replace(OutputIterator out, return out; } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_string regex_replace(const std::basic_string& s, const basic_regex& e, Formatter fmt, diff --git a/include/boost/regex/v5/regex_search.hpp b/include/boost/regex/v5/regex_search.hpp index 8eac23cf5..fbb826b28 100644 --- a/include/boost/regex/v5/regex_search.hpp +++ b/include/boost/regex/v5/regex_search.hpp @@ -25,7 +25,7 @@ namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template bool regex_search(BidiIterator first, BidiIterator last, match_results& m, const basic_regex& e, @@ -34,7 +34,7 @@ bool regex_search(BidiIterator first, BidiIterator last, return regex_search(first, last, m, e, flags, first); } -template +BOOST_REGEX_MODULE_EXPORT template bool regex_search(BidiIterator first, BidiIterator last, match_results& m, const basic_regex& e, @@ -45,13 +45,13 @@ bool regex_search(BidiIterator first, BidiIterator last, return false; BOOST_REGEX_DETAIL_NS::perl_matcher matcher(first, last, m, e, flags, base); - return matcher.find(); + return BOOST_REGEX_DETAIL_NS::factory_find(matcher); } // // regex_search convenience interfaces: // -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_search(const charT* str, match_results& m, const basic_regex& e, @@ -60,7 +60,7 @@ inline bool regex_search(const charT* str, return regex_search(str, str + traits::length(str), m, e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_search(const std::basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, @@ -69,7 +69,7 @@ inline bool regex_search(const std::basic_string& s, return regex_search(s.begin(), s.end(), m, e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template bool regex_search(BidiIterator first, BidiIterator last, const basic_regex& e, match_flag_type flags = match_default) @@ -80,10 +80,10 @@ bool regex_search(BidiIterator first, BidiIterator last, match_results m; typedef typename match_results::allocator_type match_alloc_type; BOOST_REGEX_DETAIL_NS::perl_matcher matcher(first, last, m, e, flags | regex_constants::match_any, first); - return matcher.find(); + return BOOST_REGEX_DETAIL_NS::factory_find(matcher); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_search(const charT* str, const basic_regex& e, match_flag_type flags = match_default) @@ -91,7 +91,7 @@ inline bool regex_search(const charT* str, return regex_search(str, str + traits::length(str), e, flags); } -template +BOOST_REGEX_MODULE_EXPORT template inline bool regex_search(const std::basic_string& s, const basic_regex& e, match_flag_type flags = match_default) diff --git a/include/boost/regex/v5/regex_split.hpp b/include/boost/regex/v5/regex_split.hpp index 80e302106..20bc19a87 100644 --- a/include/boost/regex/v5/regex_split.hpp +++ b/include/boost/regex/v5/regex_split.hpp @@ -93,7 +93,7 @@ bool split_pred::operator() } // namespace BOOST_REGEX_DETAIL_NS -template +BOOST_REGEX_MODULE_EXPORT template std::size_t regex_split(OutputIterator out, std::basic_string& s, const basic_regex& e, @@ -128,7 +128,7 @@ std::size_t regex_split(OutputIterator out, return init_size - max_split; } -template +BOOST_REGEX_MODULE_EXPORT template inline std::size_t regex_split(OutputIterator out, std::basic_string& s, const basic_regex& e, @@ -137,7 +137,7 @@ inline std::size_t regex_split(OutputIterator out, return regex_split(out, s, e, flags, UINT_MAX); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::size_t regex_split(OutputIterator out, std::basic_string& s) { diff --git a/include/boost/regex/v5/regex_token_iterator.hpp b/include/boost/regex/v5/regex_token_iterator.hpp index 4fbf52463..283fcd22b 100644 --- a/include/boost/regex/v5/regex_token_iterator.hpp +++ b/include/boost/regex/v5/regex_token_iterator.hpp @@ -22,8 +22,9 @@ #include #include #include - +#ifndef BOOST_REGEX_AS_MODULE #include +#endif namespace boost{ @@ -124,7 +125,7 @@ class regex_token_iterator_implementation regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&); }; -template ::value_type, class traits = regex_traits > class regex_token_iterator @@ -212,39 +213,39 @@ class regex_token_iterator } }; -typedef regex_token_iterator cregex_token_iterator; -typedef regex_token_iterator sregex_token_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_token_iterator cregex_token_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_token_iterator sregex_token_iterator; #ifndef BOOST_NO_WREGEX -typedef regex_token_iterator wcregex_token_iterator; -typedef regex_token_iterator wsregex_token_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_token_iterator wcregex_token_iterator; +BOOST_REGEX_MODULE_EXPORT typedef regex_token_iterator wsregex_token_iterator; #endif -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator make_regex_token_iterator(const charT* p, const basic_regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator(p, p+traits::length(p), e, submatch, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string& p, const basic_regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator make_regex_token_iterator(const charT* p, const basic_regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator(p, p+traits::length(p), e, submatch, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string& p, const basic_regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator make_regex_token_iterator(const charT* p, const basic_regex& e, const std::vector& submatch, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator(p, p+traits::length(p), e, submatch, m); } -template +BOOST_REGEX_MODULE_EXPORT template inline regex_token_iterator::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string& p, const basic_regex& e, const std::vector& submatch, regex_constants::match_flag_type m = regex_constants::match_default) { return regex_token_iterator::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m); diff --git a/include/boost/regex/v5/regex_traits.hpp b/include/boost/regex/v5/regex_traits.hpp index 6c64695b6..25dd542b1 100644 --- a/include/boost/regex/v5/regex_traits.hpp +++ b/include/boost/regex/v5/regex_traits.hpp @@ -33,7 +33,7 @@ namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template struct regex_traits : public implementationT { regex_traits() : implementationT() {} diff --git a/include/boost/regex/v5/regex_traits_defaults.hpp b/include/boost/regex/v5/regex_traits_defaults.hpp index 4b81441ff..1cd7adc18 100644 --- a/include/boost/regex/v5/regex_traits_defaults.hpp +++ b/include/boost/regex/v5/regex_traits_defaults.hpp @@ -24,12 +24,14 @@ #include #include #include +#ifndef BOOST_REGEX_AS_MODULE #include #include #include #include #include #include +#endif namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/regex_workaround.hpp b/include/boost/regex/v5/regex_workaround.hpp index 8cd9044ce..060e065c0 100644 --- a/include/boost/regex/v5/regex_workaround.hpp +++ b/include/boost/regex/v5/regex_workaround.hpp @@ -20,9 +20,11 @@ #define BOOST_REGEX_WORKAROUND_HPP #include +#ifndef BOOST_REGEX_AS_MODULE #include #include #include +#endif #ifndef BOOST_REGEX_STANDALONE #include diff --git a/include/boost/regex/v5/states.hpp b/include/boost/regex/v5/states.hpp index 942f0c3a8..3c3fca69c 100644 --- a/include/boost/regex/v5/states.hpp +++ b/include/boost/regex/v5/states.hpp @@ -21,8 +21,10 @@ #include +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ diff --git a/include/boost/regex/v5/sub_match.hpp b/include/boost/regex/v5/sub_match.hpp index 630070dc3..0dcb6d4d2 100644 --- a/include/boost/regex/v5/sub_match.hpp +++ b/include/boost/regex/v5/sub_match.hpp @@ -19,12 +19,14 @@ #ifndef BOOST_REGEX_V5_SUB_MATCH_HPP #define BOOST_REGEX_V5_SUB_MATCH_HPP +#ifndef BOOST_REGEX_AS_MODULE #include #include +#endif namespace boost{ -template +BOOST_REGEX_MODULE_EXPORT template struct sub_match : public std::pair { typedef typename std::iterator_traits::value_type value_type; @@ -148,167 +150,167 @@ struct sub_match : public std::pair BidiIterator end()const { return this->second; } }; -typedef sub_match csub_match; -typedef sub_match ssub_match; +BOOST_REGEX_MODULE_EXPORT typedef sub_match csub_match; +BOOST_REGEX_MODULE_EXPORT typedef sub_match ssub_match; #ifndef BOOST_NO_WREGEX -typedef sub_match wcsub_match; -typedef sub_match wssub_match; +BOOST_REGEX_MODULE_EXPORT typedef sub_match wcsub_match; +BOOST_REGEX_MODULE_EXPORT typedef sub_match wssub_match; #endif // comparison to std::basic_string<> part 1: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) <= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) >= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) { return s.compare(m.str()) > 0; } // comparison to std::basic_string<> part 2: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) > 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) <= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) { return m.str().compare(s) >= 0; } // comparison to const charT* part 1: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) > 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) >= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (const sub_match& m, typename std::iterator_traits::value_type const* s) { return m.str().compare(s) <= 0; } // comparison to const charT* part 2: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) > 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) >= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (typename std::iterator_traits::value_type const* s, const sub_match& m) { return m.str().compare(s) <= 0; } // comparison to const charT& part 1: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) > 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) >= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (const sub_match& m, typename std::iterator_traits::value_type const& s) { return m.str().compare(0, m.length(), &s, 1) <= 0; } // comparison to const charT* part 2: -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator == (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) == 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator != (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) != 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator < (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) > 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator > (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) < 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator <= (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) >= 0; } -template +BOOST_REGEX_MODULE_EXPORT template inline bool operator >= (typename std::iterator_traits::value_type const& s, const sub_match& m) { return m.str().compare(0, m.length(), &s, 1) <= 0; } // addition operators: -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type, traits, Allocator> operator + (const std::basic_string::value_type, traits, Allocator>& s, const sub_match& m) @@ -317,7 +319,7 @@ operator + (const std::basic_string +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type, traits, Allocator> operator + (const sub_match& m, const std::basic_string::value_type, traits, Allocator>& s) @@ -326,7 +328,7 @@ operator + (const sub_match& m, result.reserve(s.size() + m.length() + 1); return result.append(m.first, m.second).append(s); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type> operator + (typename std::iterator_traits::value_type const* s, const sub_match& m) @@ -335,7 +337,7 @@ operator + (typename std::iterator_traits::value_type cons result.reserve(std::char_traits::value_type>::length(s) + m.length() + 1); return result.append(s).append(m.first, m.second); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type> operator + (const sub_match& m, typename std::iterator_traits::value_type const * s) @@ -344,7 +346,7 @@ operator + (const sub_match& m, result.reserve(std::char_traits::value_type>::length(s) + m.length() + 1); return result.append(m.first, m.second).append(s); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type> operator + (typename std::iterator_traits::value_type const& s, const sub_match& m) @@ -353,7 +355,7 @@ operator + (typename std::iterator_traits::value_type cons result.reserve(m.length() + 2); return result.append(1, s).append(m.first, m.second); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type> operator + (const sub_match& m, typename std::iterator_traits::value_type const& s) @@ -362,7 +364,7 @@ operator + (const sub_match& m, result.reserve(m.length() + 2); return result.append(m.first, m.second).append(1, s); } -template +BOOST_REGEX_MODULE_EXPORT template inline std::basic_string::value_type> operator + (const sub_match& m1, const sub_match& m2) @@ -371,7 +373,7 @@ operator + (const sub_match& m1, result.reserve(m1.length() + m2.length() + 1); return result.append(m1.first, m1.second).append(m2.first, m2.second); } -template +BOOST_REGEX_MODULE_EXPORT template std::basic_ostream& operator << (std::basic_ostream& os, const sub_match& s) diff --git a/include/boost/regex/v5/syntax_type.hpp b/include/boost/regex/v5/syntax_type.hpp index 3efdf0b0f..af66ad73a 100644 --- a/include/boost/regex/v5/syntax_type.hpp +++ b/include/boost/regex/v5/syntax_type.hpp @@ -22,81 +22,81 @@ namespace boost{ namespace regex_constants{ -typedef unsigned char syntax_type; +BOOST_REGEX_MODULE_EXPORT typedef unsigned char syntax_type; // // values chosen are binary compatible with previous version: // -static const syntax_type syntax_char = 0; -static const syntax_type syntax_open_mark = 1; -static const syntax_type syntax_close_mark = 2; -static const syntax_type syntax_dollar = 3; -static const syntax_type syntax_caret = 4; -static const syntax_type syntax_dot = 5; -static const syntax_type syntax_star = 6; -static const syntax_type syntax_plus = 7; -static const syntax_type syntax_question = 8; -static const syntax_type syntax_open_set = 9; -static const syntax_type syntax_close_set = 10; -static const syntax_type syntax_or = 11; -static const syntax_type syntax_escape = 12; -static const syntax_type syntax_dash = 14; -static const syntax_type syntax_open_brace = 15; -static const syntax_type syntax_close_brace = 16; -static const syntax_type syntax_digit = 17; -static const syntax_type syntax_comma = 27; -static const syntax_type syntax_equal = 37; -static const syntax_type syntax_colon = 36; -static const syntax_type syntax_not = 53; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_char = 0; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_open_mark = 1; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_close_mark = 2; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_dollar = 3; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_caret = 4; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_dot = 5; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_star = 6; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_plus = 7; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_question = 8; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_open_set = 9; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_close_set = 10; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_or = 11; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_escape = 12; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_dash = 14; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_open_brace = 15; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_close_brace = 16; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_digit = 17; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_comma = 27; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_equal = 37; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_colon = 36; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_not = 53; // extensions: -static const syntax_type syntax_hash = 13; -static const syntax_type syntax_newline = 26; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_hash = 13; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST syntax_type syntax_newline = 26; // escapes: -typedef syntax_type escape_syntax_type; - -static const escape_syntax_type escape_type_word_assert = 18; -static const escape_syntax_type escape_type_not_word_assert = 19; -static const escape_syntax_type escape_type_control_f = 29; -static const escape_syntax_type escape_type_control_n = 30; -static const escape_syntax_type escape_type_control_r = 31; -static const escape_syntax_type escape_type_control_t = 32; -static const escape_syntax_type escape_type_control_v = 33; -static const escape_syntax_type escape_type_ascii_control = 35; -static const escape_syntax_type escape_type_hex = 34; -static const escape_syntax_type escape_type_unicode = 0; // not used -static const escape_syntax_type escape_type_identity = 0; // not used -static const escape_syntax_type escape_type_backref = syntax_digit; -static const escape_syntax_type escape_type_decimal = syntax_digit; // not used -static const escape_syntax_type escape_type_class = 22; -static const escape_syntax_type escape_type_not_class = 23; +BOOST_REGEX_MODULE_EXPORT typedef syntax_type escape_syntax_type; + +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_word_assert = 18; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_not_word_assert = 19; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_f = 29; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_n = 30; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_r = 31; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_t = 32; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_v = 33; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_ascii_control = 35; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_hex = 34; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_unicode = 0; // not used +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_identity = 0; // not used +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_backref = syntax_digit; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_decimal = syntax_digit; // not used +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_class = 22; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_not_class = 23; // extensions: -static const escape_syntax_type escape_type_left_word = 20; -static const escape_syntax_type escape_type_right_word = 21; -static const escape_syntax_type escape_type_start_buffer = 24; // for \` -static const escape_syntax_type escape_type_end_buffer = 25; // for \' -static const escape_syntax_type escape_type_control_a = 28; // for \a -static const escape_syntax_type escape_type_e = 38; // for \e -static const escape_syntax_type escape_type_E = 47; // for \Q\E -static const escape_syntax_type escape_type_Q = 48; // for \Q\E -static const escape_syntax_type escape_type_X = 49; // for \X -static const escape_syntax_type escape_type_C = 50; // for \C -static const escape_syntax_type escape_type_Z = 51; // for \Z -static const escape_syntax_type escape_type_G = 52; // for \G - -static const escape_syntax_type escape_type_property = 54; // for \p -static const escape_syntax_type escape_type_not_property = 55; // for \P -static const escape_syntax_type escape_type_named_char = 56; // for \N -static const escape_syntax_type escape_type_extended_backref = 57; // for \g -static const escape_syntax_type escape_type_reset_start_mark = 58; // for \K -static const escape_syntax_type escape_type_line_ending = 59; // for \R - -static const escape_syntax_type syntax_max = 60; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_left_word = 20; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_right_word = 21; +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_start_buffer = 24; // for \` +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_end_buffer = 25; // for \' +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_control_a = 28; // for \a +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_e = 38; // for \e +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_E = 47; // for \Q\E +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_Q = 48; // for \Q\E +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_X = 49; // for \X +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_C = 50; // for \C +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_Z = 51; // for \Z +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_G = 52; // for \G + +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_property = 54; // for \p +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_not_property = 55; // for \P +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_named_char = 56; // for \N +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_extended_backref = 57; // for \g +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_reset_start_mark = 58; // for \K +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type escape_type_line_ending = 59; // for \R + +BOOST_REGEX_MODULE_EXPORT BOOST_REGEX_STATIC_CONST escape_syntax_type syntax_max = 60; } } diff --git a/include/boost/regex/v5/unicode_iterator.hpp b/include/boost/regex/v5/unicode_iterator.hpp index 9d3dd8b96..d71737631 100644 --- a/include/boost/regex/v5/unicode_iterator.hpp +++ b/include/boost/regex/v5/unicode_iterator.hpp @@ -60,12 +60,14 @@ Accepts UTF-32 code points and forwards them on as UTF-16 code points. #ifndef BOOST_REGEX_UNICODE_ITERATOR_HPP #define BOOST_REGEX_UNICODE_ITERATOR_HPP -#include #include +#ifndef BOOST_REGEX_AS_MODULE +#include #include #include #include #include // CHAR_BIT +#endif #ifndef BOOST_REGEX_STANDALONE #include @@ -75,9 +77,9 @@ namespace boost{ namespace detail{ -static const std::uint16_t high_surrogate_base = 0xD7C0u; -static const std::uint16_t low_surrogate_base = 0xDC00u; -static const std::uint32_t ten_bit_mask = 0x3FFu; +BOOST_REGEX_STATIC_CONST std::uint16_t high_surrogate_base = 0xD7C0u; +BOOST_REGEX_STATIC_CONST std::uint16_t low_surrogate_base = 0xDC00u; +BOOST_REGEX_STATIC_CONST std::uint32_t ten_bit_mask = 0x3FFu; inline bool is_high_surrogate(std::uint16_t v) { diff --git a/include/boost/regex/v5/w32_regex_traits.hpp b/include/boost/regex/v5/w32_regex_traits.hpp index 16f7ee4ea..d6a56da53 100644 --- a/include/boost/regex/v5/w32_regex_traits.hpp +++ b/include/boost/regex/v5/w32_regex_traits.hpp @@ -23,9 +23,11 @@ #include #include +#ifndef BOOST_REGEX_AS_MODULE #ifdef BOOST_HAS_THREADS #include #endif +#endif #include #include @@ -652,7 +654,7 @@ std::shared_ptr > create_w32_regex_ } // BOOST_REGEX_DETAIL_NS -template +BOOST_REGEX_MODULE_EXPORT template class w32_regex_traits { public: diff --git a/module/regex.cxx b/module/regex.cxx new file mode 100644 index 000000000..c23d0caa5 --- /dev/null +++ b/module/regex.cxx @@ -0,0 +1,103 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if __has_include() + +#if !defined(BOOST_REGEX_WITH_ICU) + +#if defined(_MSC_FULL_VER) +#pragma message "ICU headers are available but building the Regex module with ICU support is turned OFF. Build with BOOST_REGEX_WITH_ICU=1 to turn it on, or BOOST_REGEX_WITH_ICU=0 to disable this message" +#else +# warning "ICU headers are available but building the Regex module with ICU support is turned OFF. Build with BOOST_REGEX_WITH_ICU=1 to turn it on, or BOOST_REGEX_WITH_ICU=0 to disable this message" +#endif + +#elif BOOST_REGEX_WITH_ICU +# define BOOST_REGEX_HAS_ICU_HEADERS +#endif + + +#endif + +#if defined(_WIN32) && __has_include() +#include +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BOOST_HAS_THREADS +#include +#endif +#include +#include +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#include +#endif + +#ifdef BOOST_REGEX_HAS_ICU_HEADERS +#include +#include +#include +#endif + +#define BOOST_REGEX_AS_MODULE +#define BOOST_REGEX_STANDALONE +#define BOOST_REGEX_MODULE_EXPORT export + +export module boost.regex; + +#if defined(BOOST_REGEX_USE_STD_MODULE) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +#ifdef _MSC_FULL_VER +#pragma warning(disable:5244) +#endif + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include + +#ifdef BOOST_REGEX_HAS_ICU_HEADERS +#include +#endif diff --git a/module/regex_cfind.cpp b/module/regex_cfind.cpp new file mode 100644 index 000000000..1796d5587 --- /dev/null +++ b/module/regex_cfind.cpp @@ -0,0 +1,11 @@ + +module boost.regex; + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_cmatch.cpp b/module/regex_cmatch.cpp new file mode 100644 index 000000000..ae30eb8e6 --- /dev/null +++ b/module/regex_cmatch.cpp @@ -0,0 +1,11 @@ + +module boost.regex; + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/module/regex_create_char.cpp b/module/regex_create_char.cpp new file mode 100644 index 000000000..ec216464a --- /dev/null +++ b/module/regex_create_char.cpp @@ -0,0 +1,30 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#ifndef BOOST_REGEX_DETAIL_NS +#define BOOST_REGEX_DETAIL_NS re_detail_600 +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::detail { + + std::shared_ptr::traits_type> > + create_implemenation(const char* p1, const char* p2, basic_regex::flag_type f, std::shared_ptr::traits_type> > ptraits) + { + return create_implemenation::flag_type, basic_regex::traits_type>(p1, p2, f, ptraits); + } + +} diff --git a/module/regex_create_wchar_t.cpp b/module/regex_create_wchar_t.cpp new file mode 100644 index 000000000..074993dac --- /dev/null +++ b/module/regex_create_wchar_t.cpp @@ -0,0 +1,30 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#ifndef BOOST_REGEX_DETAIL_NS +#define BOOST_REGEX_DETAIL_NS re_detail_600 +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::detail { + + std::shared_ptr::traits_type> > + create_implemenation(const wchar_t* p1, const wchar_t* p2, basic_regex::flag_type f, std::shared_ptr::traits_type> > ptraits) + { + return create_implemenation::flag_type, basic_regex::traits_type>(p1, p2, f, ptraits); + } + +} diff --git a/module/regex_nc_sfind.cpp b/module/regex_nc_sfind.cpp new file mode 100644 index 000000000..bed2018e2 --- /dev/null +++ b/module/regex_nc_sfind.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_nc_smatch.cpp b/module/regex_nc_smatch.cpp new file mode 100644 index 000000000..2208a2484 --- /dev/null +++ b/module/regex_nc_smatch.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/module/regex_nc_wsfind.cpp b/module/regex_nc_wsfind.cpp new file mode 100644 index 000000000..36c76cb71 --- /dev/null +++ b/module/regex_nc_wsfind.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_nc_wsmatch.cpp b/module/regex_nc_wsmatch.cpp new file mode 100644 index 000000000..4bae45909 --- /dev/null +++ b/module/regex_nc_wsmatch.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/module/regex_sfind.cpp b/module/regex_sfind.cpp new file mode 100644 index 000000000..7de3d2346 --- /dev/null +++ b/module/regex_sfind.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_smatch.cpp b/module/regex_smatch.cpp new file mode 100644 index 000000000..aed056201 --- /dev/null +++ b/module/regex_smatch.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, regex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/module/regex_wcfind.cpp b/module/regex_wcfind.cpp new file mode 100644 index 000000000..0e2e9955d --- /dev/null +++ b/module/regex_wcfind.cpp @@ -0,0 +1,11 @@ + +module boost.regex; + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_wcmatch.cpp b/module/regex_wcmatch.cpp new file mode 100644 index 000000000..560038310 --- /dev/null +++ b/module/regex_wcmatch.cpp @@ -0,0 +1,11 @@ + +module boost.regex; + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/module/regex_wsfind.cpp b/module/regex_wsfind.cpp new file mode 100644 index 000000000..12bef7da7 --- /dev/null +++ b/module/regex_wsfind.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_find(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.find(); + } + +} diff --git a/module/regex_wsmatch.cpp b/module/regex_wsmatch.cpp new file mode 100644 index 000000000..691882f3e --- /dev/null +++ b/module/regex_wsmatch.cpp @@ -0,0 +1,25 @@ + +module; + +#if defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135)) +#define BOOST_REGEX_USE_STD_MODULE +#endif + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && !defined(MSVC_EXPERIMENTAL_STD_MODULE) +#include +#endif + +module boost.regex; + +#if !defined(BOOST_REGEX_USE_STD_MODULE) && defined(MSVC_EXPERIMENTAL_STD_MODULE) +import std.core; +#endif + +namespace boost::re_detail_600 { + + bool factory_match(perl_matcher::allocator_type, wregex::traits_type>& m) + { + return m.match(); + } + +} diff --git a/test/concepts/module_concept_check.cpp b/test/concepts/module_concept_check.cpp new file mode 100644 index 000000000..86d981a38 --- /dev/null +++ b/test/concepts/module_concept_check.cpp @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + +#ifdef __GNUC__ +// +// For some reason, GCC chokes unless all std lib includes appear +// before module imports: +// +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +import boost.regex; + +#define BOOST_REGEX_TEST_MODULE + +#include + + +int main() +{ + boost::function_requires< + boost::RegexTraitsConcept< + boost::regex_traits + > + >(); +#ifndef BOOST_NO_STD_LOCALE + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#endif +#endif + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#endif +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex > + > + >(); +#endif +#endif + // + // now test the regex_traits concepts: + // + typedef boost::basic_regex > regex_traits_tester_type1; + boost::function_requires< + boost::BoostRegexConcept< + regex_traits_tester_type1 + > + >(); + typedef boost::basic_regex > regex_traits_tester_type2; + boost::function_requires< + boost::BaseRegexConcept< + regex_traits_tester_type2 + > + >(); + return 0; +} + + diff --git a/test/module/Jamfile.v2 b/test/module/Jamfile.v2 new file mode 100644 index 000000000..480bb0703 --- /dev/null +++ b/test/module/Jamfile.v2 @@ -0,0 +1,33 @@ +# copyright John Maddock 2022 +# 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. + +project + : requirements + multi + msvc:on + msvc:latest + gcc:-fmodules-ts + ; + +obj regex : ../../module/regex.cxx : msvc:-interface [ check-target-builds ./config//test_has_module_support : : no ] ; + +exe credit_card_example : credit_card_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe partial_regex_grep : partial_regex_grep.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe partial_regex_iterate : partial_regex_iterate.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe partial_regex_match : partial_regex_match.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_grep_example_1 : regex_grep_example_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_grep_example_2 : regex_grep_example_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_grep_example_3 : regex_grep_example_3.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_iterator_example : regex_iterator_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_match_example : regex_match_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_merge_example : regex_merge_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_replace_example : regex_replace_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_search_example : regex_search_example.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_split_example_1 : regex_split_example_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_split_example_2 : regex_split_example_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_token_iterator_eg_1 : regex_token_iterator_eg_1.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; +exe regex_token_iterator_eg_2 : regex_token_iterator_eg_2.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; + +compile ../concepts/module_concept_check.cpp regex : [ check-target-builds ./config//test_has_module_support : : no ] regex ; \ No newline at end of file diff --git a/test/module/credit_card_example.cpp b/test/module/credit_card_example.cpp new file mode 100644 index 000000000..727b1157d --- /dev/null +++ b/test/module/credit_card_example.cpp @@ -0,0 +1,79 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE credit_card_example.cpp + * VERSION see + * DESCRIPTION: Credit card number formatting code. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + + +bool validate_card_format(const std::string& s) +{ + static const boost::regex e("(\\d{4}[- ]){3}\\d{4}"); + return boost::regex_match(s, e); +} + +const boost::regex e("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z"); +const std::string machine_format("\\1\\2\\3\\4"); +const std::string human_format("\\1-\\2-\\3-\\4"); + +std::string machine_readable_card_number(const std::string& s) +{ + return boost::regex_replace(s, e, machine_format, boost::match_default | boost::format_sed); +} + +std::string human_readable_card_number(const std::string& s) +{ + return boost::regex_replace(s, e, human_format, boost::match_default | boost::format_sed); +} + +int main() +{ + using namespace std; + + string s[4] = { "0000111122223333", "0000 1111 2222 3333", + "0000-1111-2222-3333", "000-1111-2222-3333", }; + int i; + for(i = 0; i < 4; ++i) + { + cout << "validate_card_format(\"" << s[i] << "\") returned " << validate_card_format(s[i]) << endl; + } + for(i = 0; i < 4; ++i) + { + cout << "machine_readable_card_number(\"" << s[i] << "\") returned " << machine_readable_card_number(s[i]) << endl; + } + for(i = 0; i < 4; ++i) + { + cout << "human_readable_card_number(\"" << s[i] << "\") returned " << human_readable_card_number(s[i]) << endl; + } + return 0; +} + + + + diff --git a/test/module/msvc_test.bat b/test/module/msvc_test.bat new file mode 100644 index 000000000..076851459 --- /dev/null +++ b/test/module/msvc_test.bat @@ -0,0 +1,27 @@ +REM Basic command line to build everything with msvc: + +rem del *.obj +rem del *.exe +rem del *.lib + +cl /std:c++latest /EHsc /nologo /W4 /c "%VCToolsInstallDir%\modules\std.ixx" || exit 1 +cl /std:c++latest /EHsc /nologo /W4 /c /interface /I ..\..\..\.. ..\..\module\regex.cxx || exit 1 +cl /std:c++latest /EHsc /nologo /W4 /c /I ..\..\..\.. ..\..\module\*.cpp || exit 1 + +lib *.obj /OUT:regex.lib || exit 1 + +rem time < nul + +for %%f in (*.cpp) do ( + cl /std:c++latest /EHsc /nologo /W4 /I ..\..\..\.. %%f regex.lib || exit 1 +) + +rem time < nul + +rem uncomment this section to test/time non-module build: +rem for %%f in (*.cpp) do ( +rem cl /DTEST_HEADERS /std:c++latest /EHsc /nologo /W4 /I ..\..\..\.. %%f || exit 1 +rem ) + +rem time < nul + diff --git a/test/module/partial_regex_grep.cpp b/test/module/partial_regex_grep.cpp new file mode 100644 index 000000000..38cb3e47f --- /dev/null +++ b/test/module/partial_regex_grep.cpp @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE partial_regex_grep.cpp + * VERSION see + * DESCRIPTION: Search example using partial matches. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// match some kind of html tag: +boost::regex e("<[^>]*>"); +// count how many: +unsigned int tags = 0; +// saved position of partial match: +const char* next_pos = 0; + +bool grep_callback(const boost::match_results& m) +{ + if(m[0].matched == false) + { + // save position and return: + next_pos = m[0].first; + } + else + ++tags; + return true; +} + +void search(std::istream& is) +{ + char buf[4096]; + next_pos = buf + sizeof(buf); + bool have_more = true; + while(have_more) + { + // how much do we copy forward from last try: + std::ptrdiff_t leftover = (buf + sizeof(buf)) - next_pos; + // and how much is left to fill: + std::ptrdiff_t size = next_pos - buf; + // copy forward whatever we have left: + std::memmove(buf, next_pos, leftover); + // fill the rest from the stream: + is.read(buf + leftover, size); + std::streamsize read = is.gcount(); + // check to see if we've run out of text: + have_more = read == size; + // reset next_pos: + next_pos = buf + sizeof(buf); + // and then grep: + boost::regex_grep(grep_callback, + static_cast(buf), + static_cast(buf + read + leftover), + e, + boost::match_default | boost::match_partial); + } +} + +int main(int argc, char* argv[]) +{ + if(argc > 1) + { + for(int i = 1; i < argc; ++i) + { + std::ifstream fs(argv[i]); + if(fs.bad()) continue; + search(fs); + fs.close(); + } + } + else + { + std::string one(""); + std::string what; + while(what.size() < 10000) + { + what.append(one); + what.append(13, ' '); + } + std::stringstream ss; + ss.str(what); + search(ss); + } + std::cout << "total tag count was " << tags << std::endl; + return 0; +} + diff --git a/test/module/partial_regex_iterate.cpp b/test/module/partial_regex_iterate.cpp new file mode 100644 index 000000000..1e41b601d --- /dev/null +++ b/test/module/partial_regex_iterate.cpp @@ -0,0 +1,129 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE partial_regex_iterate.cpp + * VERSION see + * DESCRIPTION: Search example using partial matches. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::memmove; } +#endif + +// match some kind of html tag: +boost::regex e("<[^>]*>"); +// count how many: +unsigned int tags = 0; + +void search(std::istream& is) +{ + // buffer we'll be searching in: + char buf[4096]; + // saved position of end of partial match: + const char* next_pos = buf + sizeof(buf); + // flag to indicate whether there is more input to come: + bool have_more = true; + + while(have_more) + { + // how much do we copy forward from last try: + std::ptrdiff_t leftover = (buf + sizeof(buf)) - next_pos; + // and how much is left to fill: + std::ptrdiff_t size = next_pos - buf; + // copy forward whatever we have left: + std::memmove(buf, next_pos, leftover); + // fill the rest from the stream: + is.read(buf + leftover, size); + std::streamsize read = is.gcount(); + // check to see if we've run out of text: + have_more = read == size; + // reset next_pos: + next_pos = buf + sizeof(buf); + // and then iterate: + boost::cregex_iterator a( + buf, + buf + read + leftover, + e, + boost::match_default | boost::match_partial); + boost::cregex_iterator b; + + while(a != b) + { + if((*a)[0].matched == false) + { + // Partial match, save position and break: + next_pos = (*a)[0].first; + break; + } + else + { + // full match: + ++tags; + } + + // move to next match: + ++a; + } + } +} + +int main(int argc, char* argv[]) +{ + if(argc > 1) + { + for(int i = 1; i < argc; ++i) + { + std::ifstream fs(argv[i]); + if(fs.bad()) continue; + search(fs); + fs.close(); + } + } + else + { + std::string one(""); + std::string what; + while(what.size() < 10000) + { + what.append(one); + what.append(13, ' '); + } + std::stringstream ss; + ss.str(what); + search(ss); + } + std::cout << "total tag count was " << tags << std::endl; + return 0; +} + + + + diff --git a/test/module/partial_regex_match.cpp b/test/module/partial_regex_match.cpp new file mode 100644 index 000000000..3581eefbd --- /dev/null +++ b/test/module/partial_regex_match.cpp @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE partial_regex_match.cpp + * VERSION see + * DESCRIPTION: regex_match example using partial matches. + */ + + +//#include + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +boost::regex e("(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})"); + +bool is_possible_card_number(const std::string& input) +{ + // + // return false for partial match, true for full match, or throw for + // impossible match based on what we have so far... + boost::match_results what; + if(0 == boost::regex_match(input, what, e, boost::match_default | boost::match_partial)) + { + // the input so far could not possibly be valid so reject it: + throw std::runtime_error("Invalid data entered - this could not possibly be a valid card number"); + } + // OK so far so good, but have we finished? + if(what[0].matched) + { + // excellent, we have a result: + return true; + } + // what we have so far is only a partial match... + return false; +} + +int main(int argc, char* argv[]) +{ + try{ + std::string input; + if(argc > 1) + input = argv[1]; + else + std::cin >> input; + if(is_possible_card_number(input)) + { + std::cout << "Matched OK..." << std::endl; + } + else + std::cout << "Got a partial match..." << std::endl; + } + catch(const std::exception& e) + { + std::cout << e.what() << std::endl; + } + return 0; +} + diff --git a/test/module/regex_grep_example_1.cpp b/test/module/regex_grep_example_1.cpp new file mode 100644 index 000000000..90814b592 --- /dev/null +++ b/test/module/regex_grep_example_1.cpp @@ -0,0 +1,142 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_grep_example_1.cpp + * VERSION see + * DESCRIPTION: regex_grep example 1: searches a cpp file for class definitions. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include + +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file in the form of a string +// and searches for all the C++ class definitions, storing +// their locations in a map of strings/int's + +typedef std::map > map_type; + +const char* re = + // possibly leading whitespace: + "^[[:space:]]*" + // possible template declaration: + "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" + // class or struct: + "(class|struct)[[:space:]]*" + // leading declspec macros etc: + "(" + "\\<\\w+\\>" + "(" + "[[:blank:]]*\\([^)]*\\)" + ")?" + "[[:space:]]*" + ")*" + // the class name + "(\\<\\w*\\>)[[:space:]]*" + // template specialisation parameters + "(<[^;:{]+>)?[[:space:]]*" + // terminate in { or : + "(\\{|:[^;\\{()]*\\{)"; + +boost::regex expression(re); + +class IndexClassesPred +{ + map_type& m; + std::string::const_iterator base; +public: + IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {} + bool operator()(const boost::match_results& what) + { + // what[0] contains the whole string + // what[5] contains the class name. + // what[6] contains the template specialisation if any. + // add class name and position to map: + m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = + what[5].first - base; + return true; + } +private: + IndexClassesPred& operator=(const IndexClassesPred&); +}; + +void IndexClasses(map_type& m, const std::string& file) +{ + std::string::const_iterator start, end; + start = file.begin(); + end = file.end(); + boost::regex_grep(IndexClassesPred(m, start), start, end, expression); +} + + +using namespace std; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + std::string text; + for(int i = 1; i < argc; ++i) + { + cout << "Processing file " << argv[i] << endl; + map_type m; + std::ifstream fs(argv[i]); + load_file(text, fs); + fs.close(); + IndexClasses(m, text); + cout << m.size() << " matches found" << endl; + map_type::iterator c, d; + c = m.begin(); + d = m.end(); + while(c != d) + { + cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; + ++c; + } + } + return 0; +} + + + + + + + diff --git a/test/module/regex_grep_example_2.cpp b/test/module/regex_grep_example_2.cpp new file mode 100644 index 000000000..aa8526187 --- /dev/null +++ b/test/module/regex_grep_example_2.cpp @@ -0,0 +1,132 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_grep_example_2.cpp + * VERSION see + * DESCRIPTION: regex_grep example 2: searches a cpp file for class definitions, + * using a global callback function. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file in the form of a string +// and searches for all the C++ class definitions, storing +// their locations in a map of strings/int's + +typedef std::map > map_type; + +const char* re = + // possibly leading whitespace: + "^[[:space:]]*" + // possible template declaration: + "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" + // class or struct: + "(class|struct)[[:space:]]*" + // leading declspec macros etc: + "(" + "\\<\\w+\\>" + "(" + "[[:blank:]]*\\([^)]*\\)" + ")?" + "[[:space:]]*" + ")*" + // the class name + "(\\<\\w*\\>)[[:space:]]*" + // template specialisation parameters + "(<[^;:{]+>)?[[:space:]]*" + // terminate in { or : + "(\\{|:[^;\\{()]*\\{)"; + + +boost::regex expression(re); +map_type class_index; +std::string::const_iterator base; + +bool grep_callback(const boost::match_results& what) +{ + // what[0] contains the whole string + // what[5] contains the class name. + // what[6] contains the template specialisation if any. + // add class name and position to map: + class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = + what[5].first - base; + return true; +} + +void IndexClasses(const std::string& file) +{ + std::string::const_iterator start, end; + start = file.begin(); + end = file.end(); + base = start; + boost::regex_grep(grep_callback, start, end, expression); +} + +using namespace std; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + std::string text; + for(int i = 1; i < argc; ++i) + { + cout << "Processing file " << argv[i] << endl; + std::ifstream fs(argv[i]); + load_file(text, fs); + fs.close(); + IndexClasses(text); + cout << class_index.size() << " matches found" << endl; + map_type::iterator c, d; + c = class_index.begin(); + d = class_index.end(); + while(c != d) + { + cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; + ++c; + } + class_index.erase(class_index.begin(), class_index.end()); + } + return 0; +} + + + diff --git a/test/module/regex_grep_example_3.cpp b/test/module/regex_grep_example_3.cpp new file mode 100644 index 000000000..87369ba66 --- /dev/null +++ b/test/module/regex_grep_example_3.cpp @@ -0,0 +1,144 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_grep_example_3.cpp + * VERSION see + * DESCRIPTION: regex_grep example 3: searches a cpp file for class definitions, + * using a bound member function callback. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file in the form of a string +// and searches for all the C++ class definitions, storing +// their locations in a map of strings/int's + +typedef std::map > map_type; + +const char* re = + // possibly leading whitespace: + "^[[:space:]]*" + // possible template declaration: + "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" + // class or struct: + "(class|struct)[[:space:]]*" + // leading declspec macros etc: + "(" + "\\<\\w+\\>" + "(" + "[[:blank:]]*\\([^)]*\\)" + ")?" + "[[:space:]]*" + ")*" + // the class name + "(\\<\\w*\\>)[[:space:]]*" + // template specialisation parameters + "(<[^;:{]+>)?[[:space:]]*" + // terminate in { or : + "(\\{|:[^;\\{()]*\\{)"; + + +class class_index +{ + boost::regex expression; + map_type index; + std::string::const_iterator base; + + bool grep_callback(boost::match_results what); +public: + map_type& get_map() { return index; } + void IndexClasses(const std::string& file); + class_index() + : expression(re) {} +}; + +bool class_index::grep_callback(boost::match_results what) +{ + // what[0] contains the whole string + // what[5] contains the class name. + // what[6] contains the template specialisation if any. + // add class name and position to map: + index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = + what[5].first - base; + return true; +} + +void class_index::IndexClasses(const std::string& file) +{ + std::string::const_iterator start, end; + start = file.begin(); + end = file.end(); + base = start; + boost::regex_grep([&](boost::match_resultsconst & what)->bool { return this->grep_callback(what); }, + start, + end, + expression); +} + +using namespace std; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + std::string text; + for(int i = 1; i < argc; ++i) + { + cout << "Processing file " << argv[i] << endl; + std::ifstream fs(argv[i]); + load_file(text, fs); + fs.close(); + class_index idx; + idx.IndexClasses(text); + cout << idx.get_map().size() << " matches found" << endl; + map_type::iterator c, d; + c = idx.get_map().begin(); + d = idx.get_map().end(); + while(c != d) + { + cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; + ++c; + } + } + return 0; +} + diff --git a/test/module/regex_iterator_example.cpp b/test/module/regex_iterator_example.cpp new file mode 100644 index 000000000..855321e30 --- /dev/null +++ b/test/module/regex_iterator_example.cpp @@ -0,0 +1,126 @@ +/* + * + * Copyright (c) 2003-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_iterator_example_2.cpp + * VERSION see + * DESCRIPTION: regex_iterator example 2: searches a cpp file for class definitions, + * using global data. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +using namespace std; + +// purpose: +// takes the contents of a file in the form of a string +// and searches for all the C++ class definitions, storing +// their locations in a map of strings/int's + +typedef std::map > map_type; + +const char* re = + // possibly leading whitespace: + "^[[:space:]]*" + // possible template declaration: + "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" + // class or struct: + "(class|struct)[[:space:]]*" + // leading declspec macros etc: + "(" + "\\<\\w+\\>" + "(" + "[[:blank:]]*\\([^)]*\\)" + ")?" + "[[:space:]]*" + ")*" + // the class name + "(\\<\\w*\\>)[[:space:]]*" + // template specialisation parameters + "(<[^;:{]+>)?[[:space:]]*" + // terminate in { or : + "(\\{|:[^;\\{()]*\\{)"; + + +boost::regex expression(re); +map_type class_index; + +bool regex_callback(const boost::match_results& what) +{ + // what[0] contains the whole string + // what[5] contains the class name. + // what[6] contains the template specialisation if any. + // add class name and position to map: + class_index[what[5].str() + what[6].str()] = what.position(5); + return true; +} + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + std::string text; + for(int i = 1; i < argc; ++i) + { + cout << "Processing file " << argv[i] << endl; + std::ifstream fs(argv[i]); + load_file(text, fs); + fs.close(); + // construct our iterators: + boost::sregex_iterator m1(text.begin(), text.end(), expression); + boost::sregex_iterator m2; + std::for_each(m1, m2, ®ex_callback); + // copy results: + cout << class_index.size() << " matches found" << endl; + map_type::iterator c, d; + c = class_index.begin(); + d = class_index.end(); + while(c != d) + { + cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; + ++c; + } + class_index.erase(class_index.begin(), class_index.end()); + } + return 0; +} + + + diff --git a/test/module/regex_match_example.cpp b/test/module/regex_match_example.cpp new file mode 100644 index 000000000..9cb360392 --- /dev/null +++ b/test/module/regex_match_example.cpp @@ -0,0 +1,93 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_match_example.cpp + * VERSION see + * DESCRIPTION: ftp based regex_match example. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +using namespace boost; + +regex expression("^([0-9]+)(\\-| |$)(.*)$"); + +// process_ftp: +// on success returns the ftp response code, and fills +// msg with the ftp response message. +int process_ftp(const char* response, std::string* msg) +{ + cmatch what; + if(regex_match(response, what, expression)) + { + // what[0] contains the whole string + // what[1] contains the response code + // what[2] contains the separator character + // what[3] contains the text message. + if(msg) + msg->assign(what[3].first, what[3].second); + return std::atoi(what[1].first); + } + // failure did not match + if(msg) + msg->erase(); + return -1; +} + +int main(int argc, const char*[]) +{ + using namespace std; + std::string in, out; + do + { + if(argc == 1) + { + cout << "enter test string" << endl; + getline(cin, in); + if(in == "quit") + break; + } + else + in = "100 this is an ftp message text"; + int result; + result = process_ftp(in.c_str(), &out); + if(result != -1) + { + cout << "Match found:" << endl; + cout << "Response code: " << result << endl; + cout << "Message text: " << out << endl; + } + else + { + cout << "Match not found" << endl; + } + cout << endl; + } while(argc == 1); + return 0; +} + diff --git a/test/module/regex_merge_example.cpp b/test/module/regex_merge_example.cpp new file mode 100644 index 000000000..509637db6 --- /dev/null +++ b/test/module/regex_merge_example.cpp @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_merge_example.cpp + * VERSION see + * DESCRIPTION: regex_merge example: + * converts a C++ file to syntax highlighted HTML. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file and transform to +// syntax highlighted code in html format + +boost::regex e1, e2; +extern const char* expression_text; +extern const char* format_string; +extern const char* pre_expression; +extern const char* pre_format; +extern const char* header_text; +extern const char* footer_text; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + try{ + e1.assign(expression_text); + e2.assign(pre_expression); + for(int i = 1; i < argc; ++i) + { + std::cout << "Processing file " << argv[i] << std::endl; + std::ifstream fs(argv[i]); + std::string in; + load_file(in, fs); + fs.close(); + std::string out_name = std::string(argv[i]) + std::string(".htm"); + std::ofstream os(out_name.c_str()); + os << header_text; + // strip '<' and '>' first by outputting to a + // temporary string stream + std::ostringstream t(std::ios::out | std::ios::binary); + std::ostream_iterator oi(t); + boost::regex_merge(oi, in.begin(), in.end(), e2, pre_format, boost::match_default | boost::format_all); + // then output to final output stream + // adding syntax highlighting: + std::string s(t.str()); + std::ostream_iterator out(os); + boost::regex_merge(out, s.begin(), s.end(), e1, format_string, boost::match_default | boost::format_all); + os << footer_text; + os.close(); + } + } + catch(...) + { return -1; } + return 0; +} + +const char* pre_expression = "(<)|(>)|\\r"; +const char* pre_format = "(?1<)(?2>)"; + + +const char* expression_text = // preprocessor directives: index 1 + "(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|" + // comment: index 2 + "(//[^\\n]*|/\\*.*?\\*/)|" + // literals: index 3 + "\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|" + // string literals: index 4 + "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|" + // keywords: index 5 + "\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import" + "|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall" + "|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool" + "|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete" + "|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto" + "|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected" + "|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast" + "|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned" + "|using|virtual|void|volatile|wchar_t|while)\\>" + ; + +const char* format_string = "(?1$&)" + "(?2$&)" + "(?3$&)" + "(?4$&)" + "(?5$&)"; + +const char* header_text = "\n\n" + "Auto-generated html formated source\n" + "\n" + "\n" + "\n" + "

\n
";
+
+const char* footer_text = "
\n\n\n"; + diff --git a/test/module/regex_replace_example.cpp b/test/module/regex_replace_example.cpp new file mode 100644 index 000000000..e5f5d60c2 --- /dev/null +++ b/test/module/regex_replace_example.cpp @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_replace_example.cpp + * VERSION see + * DESCRIPTION: regex_replace example: + * converts a C++ file to syntax highlighted HTML. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file and transform to +// syntax highlighted code in html format + +boost::regex e1, e2; +extern const char* expression_text; +extern const char* format_string; +extern const char* pre_expression; +extern const char* pre_format; +extern const char* header_text; +extern const char* footer_text; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + try{ + e1.assign(expression_text); + e2.assign(pre_expression); + for(int i = 1; i < argc; ++i) + { + std::cout << "Processing file " << argv[i] << std::endl; + std::ifstream fs(argv[i]); + std::string in; + load_file(in, fs); + fs.close(); + std::string out_name = std::string(argv[i]) + std::string(".htm"); + std::ofstream os(out_name.c_str()); + os << header_text; + // strip '<' and '>' first by outputting to a + // temporary string stream + std::ostringstream t(std::ios::out | std::ios::binary); + std::ostream_iterator oi(t); + boost::regex_replace(oi, in.begin(), in.end(), e2, pre_format, boost::match_default | boost::format_all); + // then output to final output stream + // adding syntax highlighting: + std::string s(t.str()); + std::ostream_iterator out(os); + boost::regex_replace(out, s.begin(), s.end(), e1, format_string, boost::match_default | boost::format_all); + os << footer_text; + os.close(); + } + } + catch(...) + { return -1; } + return 0; +} + +const char* pre_expression = "(<)|(>)|(&)|\\r"; +const char* pre_format = "(?1<)(?2>)(?3&)"; + + +const char* expression_text = // preprocessor directives: index 1 + "(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|" + // comment: index 2 + "(//[^\\n]*|/\\*.*?\\*/)|" + // literals: index 3 + "\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|" + // string literals: index 4 + "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|" + // keywords: index 5 + "\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import" + "|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall" + "|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool" + "|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete" + "|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto" + "|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected" + "|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast" + "|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned" + "|using|virtual|void|volatile|wchar_t|while)\\>" + ; + +const char* format_string = "(?1$&)" + "(?2$&)" + "(?3$&)" + "(?4$&)" + "(?5$&)"; + +const char* header_text = "\n\n" + "Auto-generated html formated source\n" + "\n" + "\n" + "\n" + "

\n
";
+
+const char* footer_text = "
\n\n\n"; + + + + + + + + + + + + diff --git a/test/module/regex_search_example.cpp b/test/module/regex_search_example.cpp new file mode 100644 index 000000000..72afe30a1 --- /dev/null +++ b/test/module/regex_search_example.cpp @@ -0,0 +1,139 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_search_example.cpp + * VERSION see + * DESCRIPTION: regex_search example: searches a cpp file for class definitions. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +// purpose: +// takes the contents of a file in the form of a string +// and searches for all the C++ class definitions, storing +// their locations in a map of strings/int's + +typedef std::map > map_type; + +const char* re = + // possibly leading whitespace: + "^[[:space:]]*" + // possible template declaration: + "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" + // class or struct: + "(class|struct)[[:space:]]*" + // leading declspec macros etc: + "(" + "\\<\\w+\\>" + "(" + "[[:blank:]]*\\([^)]*\\)" + ")?" + "[[:space:]]*" + ")*" + // the class name + "(\\<\\w*\\>)[[:space:]]*" + // template specialisation parameters + "(<[^;:{]+>)?[[:space:]]*" + // terminate in { or : + "(\\{|:[^;\\{()]*\\{)"; + + +boost::regex expression(re); + +void IndexClasses(map_type& m, const std::string& file) +{ + std::string::const_iterator start, end; + start = file.begin(); + end = file.end(); + boost::match_results what; + boost::match_flag_type flags = boost::match_default; + while(boost::regex_search(start, end, what, expression, flags)) + { + // what[0] contains the whole string + // what[5] contains the class name. + // what[6] contains the template specialisation if any. + // add class name and position to map: + m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = + what[5].first - file.begin(); + // update search position: + start = what[0].second; + // update flags: + flags |= boost::match_prev_avail; + flags |= boost::match_not_bob; + } +} + + +using namespace std; + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, const char** argv) +{ + std::string text; + for(int i = 1; i < argc; ++i) + { + cout << "Processing file " << argv[i] << endl; + map_type m; + std::ifstream fs(argv[i]); + load_file(text, fs); + fs.close(); + IndexClasses(m, text); + cout << m.size() << " matches found" << endl; + map_type::iterator c, d; + c = m.begin(); + d = m.end(); + while(c != d) + { + cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; + ++c; + } + } + return 0; +} + + + + + + + + + diff --git a/test/module/regex_split_example_1.cpp b/test/module/regex_split_example_1.cpp new file mode 100644 index 000000000..8963c7d8c --- /dev/null +++ b/test/module/regex_split_example_1.cpp @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_split_example_1.cpp + * VERSION see + * DESCRIPTION: regex_split example: split a string into tokens. + */ + + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +Simport std.core; +#else +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +unsigned tokenise(std::list& l, std::string& s) +{ + return boost::regex_split(std::back_inserter(l), s); +} + +using namespace std; + +int main(int argc, const char*[]) +{ + string s; + list l; + do{ + if(argc == 1) + { + cout << "Enter text to split (or \"quit\" to exit): "; + getline(cin, s); + if(s == "quit") break; + } + else + s = "This is a string of tokens"; + unsigned result = tokenise(l, s); + cout << result << " tokens found" << endl; + cout << "The remaining text is: \"" << s << "\"" << endl; + while(l.size()) + { + s = *(l.begin()); + l.pop_front(); + cout << s << endl; + } + }while(argc == 1); + return 0; +} + + diff --git a/test/module/regex_split_example_2.cpp b/test/module/regex_split_example_2.cpp new file mode 100644 index 000000000..21bbeb5d5 --- /dev/null +++ b/test/module/regex_split_example_2.cpp @@ -0,0 +1,97 @@ +/* + * + * Copyright (c) 1998-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_split_example_2.cpp + * VERSION see + * DESCRIPTION: regex_split example: spit out linked URL's. + */ + + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"", + boost::regex::normal | boost::regex::icase); + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + // + // attempt to grow string buffer to match file size, + // this doesn't always work... + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + // use logarithmic growth stategy, in case + // in_avail (above) returned zero: + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, char** argv) +{ + std::string s; + std::list l; + int i; + for(i = 1; i < argc; ++i) + { + std::cout << "Findings URL's in " << argv[i] << ":" << std::endl; + s.erase(); + std::ifstream is(argv[i]); + load_file(s, is); + is.close(); + boost::regex_split(std::back_inserter(l), s, e); + while(l.size()) + { + s = *(l.begin()); + l.pop_front(); + std::cout << s << std::endl; + } + } + // + // alternative method: + // split one match at a time and output direct to + // cout via ostream_iterator.... + // + for(i = 1; i < argc; ++i) + { + std::cout << "Findings URL's in " << argv[i] << ":" << std::endl; + s.erase(); + std::ifstream is(argv[i]); + load_file(s, is); + is.close(); + while(boost::regex_split(std::ostream_iterator(std::cout), s, e, boost::match_default, 1)) std::cout << std::endl; + } + + return 0; +} + + diff --git a/test/module/regex_token_iterator_eg_1.cpp b/test/module/regex_token_iterator_eg_1.cpp new file mode 100644 index 000000000..d0f8473a0 --- /dev/null +++ b/test/module/regex_token_iterator_eg_1.cpp @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2003-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_token_iterator_example_1.cpp + * VERSION see + * DESCRIPTION: regex_token_iterator example: split a string into tokens. + */ + + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +using namespace std; + +int main(int argc, const char*[]) +{ + string s; + do{ + if(argc == 1) + { + cout << "Enter text to split (or \"quit\" to exit): "; + getline(cin, s); + if(s == "quit") break; + } + else + s = "This is a string of tokens"; + + boost::regex re("\\s+"); + boost::sregex_token_iterator i(s.begin(), s.end(), re, -1); + boost::sregex_token_iterator j; + + unsigned count = 0; + while(i != j) + { + cout << *i++ << endl; + count++; + } + cout << "There were " << count << " tokens found." << endl; + + }while(argc == 1); + return 0; +} + + diff --git a/test/module/regex_token_iterator_eg_2.cpp b/test/module/regex_token_iterator_eg_2.cpp new file mode 100644 index 000000000..7a20855c1 --- /dev/null +++ b/test/module/regex_token_iterator_eg_2.cpp @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2003-2022 + * John Maddock + * + * Use, modification and distribution are subject to 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) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_token_iterator_example_2.cpp + * VERSION see + * DESCRIPTION: regex_token_iterator example: spit out linked URL's. + */ + +#if (defined(__cpp_lib_modules) || (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 193833135))) && !defined(TEST_HEADERS) +import std; +#elif defined(MSVC_EXPERIMENTAL_STD_MODULE) && !defined(TEST_HEADERS) +import std.core; +#else +#include +#include +#include +#endif + +#ifdef TEST_HEADERS +#include +#else +import boost.regex; +#endif + +boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"", + boost::regex::normal | boost::regex::icase); + +void load_file(std::string& s, std::istream& is) +{ + s.erase(); + if(is.bad()) return; + // + // attempt to grow string buffer to match file size, + // this doesn't always work... + s.reserve(static_cast(is.rdbuf()->in_avail())); + char c; + while(is.get(c)) + { + // use logarithmic growth stategy, in case + // in_avail (above) returned zero: + if(s.capacity() == s.size()) + s.reserve(s.capacity() * 3); + s.append(1, c); + } +} + +int main(int argc, char** argv) +{ + std::string s; + int i; + for(i = 1; i < argc; ++i) + { + std::cout << "Findings URL's in " << argv[i] << ":" << std::endl; + s.erase(); + std::ifstream is(argv[i]); + load_file(s, is); + is.close(); + boost::sregex_token_iterator i(s.begin(), s.end(), e, 1); + boost::sregex_token_iterator j; + while(i != j) + { + std::cout << *i++ << std::endl; + } + } + // + // alternative method: + // test the array-literal constructor, and split out the whole + // match as well as $1.... + // + for(i = 1; i < argc; ++i) + { + std::cout << "Findings URL's in " << argv[i] << ":" << std::endl; + s.erase(); + std::ifstream is(argv[i]); + load_file(s, is); + is.close(); + const int subs[] = {1, 0,}; + boost::sregex_token_iterator i(s.begin(), s.end(), e, subs); + boost::sregex_token_iterator j; + while(i != j) + { + std::cout << *i++ << std::endl; + } + } + + return 0; +} + + diff --git a/test/module/test_clang.sh b/test/module/test_clang.sh new file mode 100755 index 000000000..ef30af8bd --- /dev/null +++ b/test/module/test_clang.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# +# Builds all of the tests in this folder using clang modules +# +: ${CXX:="clang++"} +: ${CXXFLAGS:="-std=c++20 -g -I../../../.."} + +rm *.o *.pcm *.exe + +cmd="$CXX $CXXFLAGS -x c++-module ../../module/regex.cxx --precompile -o boost.regex.pcm" +echo $cmd +$cmd || exit 1 +cmd="$CXX $CXXFLAGS boost.regex.pcm -c -o regex.o" +echo $cmd +$cmd || exit 1 +cmd="$CXX $CXXFLAGS -fprebuilt-module-path=. -c ../../module/*.cpp" +echo $cmd +$cmd || exit 1 + + +for file in *.cpp; do + +cmd="$CXX $CXXFLAGS -fprebuilt-module-path=. $file *.o -o ${file%.*}.exe" +echo $cmd +$cmd || exit 1 + +done