1 /* 2 * DQt - D bindings for the Qt Toolkit 3 * 4 * GNU Lesser General Public License Usage 5 * This file may be used under the terms of the GNU Lesser 6 * General Public License version 3 as published by the Free Software 7 * Foundation and appearing in the file LICENSE.LGPL3 included in the 8 * packaging of this file. Please review the following information to 9 * ensure the GNU Lesser General Public License version 3 requirements 10 * will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 11 */ 12 module qt.core.regularexpression; 13 extern(C++): 14 15 import qt.config; 16 import qt.core.flags; 17 import qt.core.global; 18 import qt.core.namespace; 19 import qt.core.shareddata; 20 import qt.core.string; 21 import qt.core.stringlist; 22 import qt.core.stringview; 23 import qt.core.typeinfo; 24 import qt.helpers; 25 26 /+ QT_REQUIRE_CONFIG(regularexpression); +/ 27 28 29 30 struct QRegularExpressionPrivate; 31 32 /+ QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionPrivate, Q_CORE_EXPORT) 33 Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed = 0) noexcept; +/ 34 35 /// Binding for C++ class [QRegularExpression](https://doc.qt.io/qt-6/qregularexpression.html). 36 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QRegularExpression 37 { 38 public: 39 enum PatternOption { 40 NoPatternOption = 0x0000, 41 CaseInsensitiveOption = 0x0001, 42 DotMatchesEverythingOption = 0x0002, 43 MultilineOption = 0x0004, 44 ExtendedPatternSyntaxOption = 0x0008, 45 InvertedGreedinessOption = 0x0010, 46 DontCaptureOption = 0x0020, 47 UseUnicodePropertiesOption = 0x0040, 48 // Formerly (no-ops deprecated in 5.12, removed 6.0): 49 // OptimizeOnFirstUsageOption = 0x0080, 50 // DontAutomaticallyOptimizeOption = 0x0100, 51 } 52 /+ Q_DECLARE_FLAGS(PatternOptions, PatternOption) +/ 53 alias PatternOptions = QFlags!(PatternOption); 54 PatternOptions patternOptions() const; 55 void setPatternOptions(PatternOptions options); 56 57 @disable this(); 58 pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this)))) 59 ref typeof(this) rawConstructor(); 60 static typeof(this) create() 61 { 62 typeof(this) r = typeof(this).init; 63 r.rawConstructor(); 64 return r; 65 } 66 67 /+ explicit +/this(ref const(QString) pattern, PatternOptions options = PatternOption.NoPatternOption); 68 @disable this(this); 69 this(ref const(QRegularExpression) re); 70 /+ QRegularExpression(QRegularExpression &&re) = default; +/ 71 ~this(); 72 /+ref QRegularExpression operator =(ref const(QRegularExpression) re);+/ 73 /+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRegularExpression) +/ 74 75 /+ void swap(QRegularExpression &other) noexcept { d.swap(other.d); } +/ 76 77 QString pattern() const; 78 void setPattern(ref const(QString) pattern); 79 80 /+ [[nodiscard]] +/ 81 bool isValid() const; 82 qsizetype patternErrorOffset() const; 83 QString errorString() const; 84 85 int captureCount() const; 86 QStringList namedCaptureGroups() const; 87 88 enum MatchType { 89 NormalMatch = 0, 90 PartialPreferCompleteMatch, 91 PartialPreferFirstMatch, 92 NoMatch 93 } 94 95 enum MatchOption { 96 NoMatchOption = 0x0000, 97 AnchorAtOffsetMatchOption = 0x0001, 98 AnchoredMatchOption /+ Q_DECL_ENUMERATOR_DEPRECATED_X( 99 "Use AnchorAtOffsetMatchOption instead") +/ = MatchOption.AnchorAtOffsetMatchOption, // Rename@Qt6.0 100 DontCheckSubjectStringMatchOption = 0x0002 101 } 102 /+ Q_DECLARE_FLAGS(MatchOptions, MatchOption) +/ 103 alias MatchOptions = QFlags!(MatchOption); 104 /+ [[nodiscard]] +/ 105 QRegularExpressionMatch match(ref const(QString) subject, 106 qsizetype offset = 0, 107 MatchType matchType = MatchType.NormalMatch, 108 MatchOptions matchOptions = MatchOption.NoMatchOption) const; 109 110 /+ [[nodiscard]] +/ 111 QRegularExpressionMatch match(QStringView subjectView, 112 qsizetype offset = 0, 113 MatchType matchType = MatchType.NormalMatch, 114 MatchOptions matchOptions = MatchOption.NoMatchOption) const; 115 116 /+ [[nodiscard]] +/ 117 QRegularExpressionMatchIterator globalMatch(ref const(QString) subject, 118 qsizetype offset = 0, 119 MatchType matchType = MatchType.NormalMatch, 120 MatchOptions matchOptions = MatchOption.NoMatchOption) const; 121 122 /+ [[nodiscard]] +/ 123 QRegularExpressionMatchIterator globalMatch(QStringView subjectView, 124 qsizetype offset = 0, 125 MatchType matchType = MatchType.NormalMatch, 126 MatchOptions matchOptions = MatchOption.NoMatchOption) const; 127 128 void optimize() const; 129 130 enum WildcardConversionOption { 131 DefaultWildcardConversion = 0x0, 132 UnanchoredWildcardConversion = 0x1 133 } 134 /+ Q_DECLARE_FLAGS(WildcardConversionOptions, WildcardConversionOption) +/ 135 alias WildcardConversionOptions = QFlags!(WildcardConversionOption); 136 static if(QT_STRINGVIEW_LEVEL < 2) 137 { 138 static QString escape(ref const(QString) str) 139 { 140 return escape(qToStringViewIgnoringNull(str)); 141 } 142 143 static QString wildcardToRegularExpression(ref const(QString) str, WildcardConversionOptions options = WildcardConversionOption.DefaultWildcardConversion) 144 { 145 return wildcardToRegularExpression(qToStringViewIgnoringNull(str), options); 146 } 147 148 pragma(inline, true) static QString anchoredPattern(ref const(QString) expression) 149 { 150 return anchoredPattern(qToStringViewIgnoringNull(expression)); 151 } 152 } 153 154 static QString escape(QStringView str); 155 static QString wildcardToRegularExpression(QStringView str, WildcardConversionOptions options = WildcardConversionOption.DefaultWildcardConversion); 156 static QString anchoredPattern(QStringView expression); 157 158 static QRegularExpression fromWildcard(QStringView pattern, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseInsensitive, 159 WildcardConversionOptions options = WildcardConversionOption.DefaultWildcardConversion); 160 161 /+bool operator ==(ref const(QRegularExpression) re) const;+/ 162 /+pragma(inline, true) bool operator !=(ref const(QRegularExpression) re) const { return !operator==(re); }+/ 163 164 private: 165 /+ friend struct QRegularExpressionPrivate; +/ 166 /+ friend class QRegularExpressionMatch; +/ 167 /+ friend struct QRegularExpressionMatchPrivate; +/ 168 /+ friend class QRegularExpressionMatchIterator; +/ 169 /+ friend Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed) noexcept; +/ 170 171 this(ref QRegularExpressionPrivate dd); 172 QExplicitlySharedDataPointer!(QRegularExpressionPrivate) d; 173 mixin(CREATE_CONVENIENCE_WRAPPERS); 174 } 175 /+pragma(inline, true) QFlags!(QRegularExpression.PatternOptions.enum_type) operator |(QRegularExpression.PatternOptions.enum_type f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/{return QFlags!(QRegularExpression.PatternOptions.enum_type)(f1)|f2;}+/ 176 /+pragma(inline, true) QFlags!(QRegularExpression.PatternOptions.enum_type) operator |(QRegularExpression.PatternOptions.enum_type f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/{return f2|f1;}+/ 177 /+pragma(inline, true) QFlags!(QRegularExpression.PatternOptions.enum_type) operator &(QRegularExpression.PatternOptions.enum_type f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/{return QFlags!(QRegularExpression.PatternOptions.enum_type)(f1)&f2;}+/ 178 /+pragma(inline, true) QFlags!(QRegularExpression.PatternOptions.enum_type) operator &(QRegularExpression.PatternOptions.enum_type f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/{return f2&f1;}+/ 179 /+pragma(inline, true) void operator +(QRegularExpression.PatternOptions.enum_type f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/;+/ 180 /+pragma(inline, true) void operator +(QRegularExpression.PatternOptions.enum_type f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/;+/ 181 /+pragma(inline, true) void operator +(int f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/;+/ 182 /+pragma(inline, true) void operator -(QRegularExpression.PatternOptions.enum_type f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/;+/ 183 /+pragma(inline, true) void operator -(QRegularExpression.PatternOptions.enum_type f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/;+/ 184 /+pragma(inline, true) void operator -(int f1, QFlags!(QRegularExpression.PatternOptions.enum_type) f2)/+noexcept+/;+/ 185 /+pragma(inline, true) QIncompatibleFlag operator |(QRegularExpression.PatternOptions.enum_type f1, int f2)/+noexcept+/{return QIncompatibleFlag(int(f1)|f2);}+/ 186 /+pragma(inline, true) void operator +(int f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/;+/ 187 /+pragma(inline, true) void operator +(QRegularExpression.PatternOptions.enum_type f1, int f2)/+noexcept+/;+/ 188 /+pragma(inline, true) void operator -(int f1, QRegularExpression.PatternOptions.enum_type f2)/+noexcept+/;+/ 189 /+pragma(inline, true) void operator -(QRegularExpression.PatternOptions.enum_type f1, int f2)/+noexcept+/;+/ 190 191 /+ Q_DECLARE_SHARED(QRegularExpression) 192 Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions) +/ 193 /+pragma(inline, true) QFlags!(QRegularExpression.MatchOptions.enum_type) operator |(QRegularExpression.MatchOptions.enum_type f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/{return QFlags!(QRegularExpression.MatchOptions.enum_type)(f1)|f2;}+/ 194 /+pragma(inline, true) QFlags!(QRegularExpression.MatchOptions.enum_type) operator |(QRegularExpression.MatchOptions.enum_type f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/{return f2|f1;}+/ 195 /+pragma(inline, true) QFlags!(QRegularExpression.MatchOptions.enum_type) operator &(QRegularExpression.MatchOptions.enum_type f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/{return QFlags!(QRegularExpression.MatchOptions.enum_type)(f1)&f2;}+/ 196 /+pragma(inline, true) QFlags!(QRegularExpression.MatchOptions.enum_type) operator &(QRegularExpression.MatchOptions.enum_type f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/{return f2&f1;}+/ 197 /+pragma(inline, true) void operator +(QRegularExpression.MatchOptions.enum_type f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/;+/ 198 /+pragma(inline, true) void operator +(QRegularExpression.MatchOptions.enum_type f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/;+/ 199 /+pragma(inline, true) void operator +(int f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/;+/ 200 /+pragma(inline, true) void operator -(QRegularExpression.MatchOptions.enum_type f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/;+/ 201 /+pragma(inline, true) void operator -(QRegularExpression.MatchOptions.enum_type f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/;+/ 202 /+pragma(inline, true) void operator -(int f1, QFlags!(QRegularExpression.MatchOptions.enum_type) f2)/+noexcept+/;+/ 203 /+pragma(inline, true) QIncompatibleFlag operator |(QRegularExpression.MatchOptions.enum_type f1, int f2)/+noexcept+/{return QIncompatibleFlag(int(f1)|f2);}+/ 204 /+pragma(inline, true) void operator +(int f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/;+/ 205 /+pragma(inline, true) void operator +(QRegularExpression.MatchOptions.enum_type f1, int f2)/+noexcept+/;+/ 206 /+pragma(inline, true) void operator -(int f1, QRegularExpression.MatchOptions.enum_type f2)/+noexcept+/;+/ 207 /+pragma(inline, true) void operator -(QRegularExpression.MatchOptions.enum_type f1, int f2)/+noexcept+/;+/ 208 /+ Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions) 209 #ifndef QT_NO_DATASTREAM 210 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re); 211 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re); 212 #endif 213 214 #ifndef QT_NO_DEBUG_STREAM 215 Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re); 216 Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions); 217 #endif +/ 218 219 struct QRegularExpressionMatchPrivate; 220 /+ QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchPrivate, Q_CORE_EXPORT) +/ 221 /// Binding for C++ class [QRegularExpressionMatch](https://doc.qt.io/qt-6/qregularexpressionmatch.html). 222 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QRegularExpressionMatch 223 { 224 public: 225 @disable this(); 226 pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this)))) 227 ref typeof(this) rawConstructor(); 228 static typeof(this) create() 229 { 230 typeof(this) r = typeof(this).init; 231 r.rawConstructor(); 232 return r; 233 } 234 235 ~this(); 236 @disable this(this); 237 this(ref const(QRegularExpressionMatch) match); 238 /+ QRegularExpressionMatch(QRegularExpressionMatch &&match) = default; +/ 239 /+ref QRegularExpressionMatch operator =(ref const(QRegularExpressionMatch) match);+/ 240 /+ QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept 241 { d.swap(match.d); return *this; } +/ 242 /+ void swap(QRegularExpressionMatch &other) noexcept { d.swap(other.d); } +/ 243 244 QRegularExpression regularExpression() const; 245 QRegularExpression.MatchType matchType() const; 246 QRegularExpression.MatchOptions matchOptions() const; 247 248 bool hasMatch() const; 249 bool hasPartialMatch() const; 250 251 bool isValid() const; 252 253 int lastCapturedIndex() const; 254 255 QString captured(int nth = 0) const; 256 QStringView capturedView(int nth = 0) const; 257 258 static if(QT_STRINGVIEW_LEVEL < 2) 259 { 260 QString captured(ref const(QString) name) const 261 { return captured(QStringView(name)); } 262 } 263 264 QString captured(QStringView name) const; 265 QStringView capturedView(QStringView name) const; 266 267 QStringList capturedTexts() const; 268 269 qsizetype capturedStart(int nth = 0) const; 270 qsizetype capturedLength(int nth = 0) const; 271 qsizetype capturedEnd(int nth = 0) const; 272 273 static if(QT_STRINGVIEW_LEVEL < 2) 274 { 275 qsizetype capturedStart(ref const(QString) name) const 276 { return capturedStart(QStringView(name)); } 277 qsizetype capturedLength(ref const(QString) name) const 278 { return capturedLength(QStringView(name)); } 279 qsizetype capturedEnd(ref const(QString) name) const 280 { return capturedEnd(QStringView(name)); } 281 } 282 283 qsizetype capturedStart(QStringView name) const; 284 qsizetype capturedLength(QStringView name) const; 285 qsizetype capturedEnd(QStringView name) const; 286 287 private: 288 /+ friend class QRegularExpression; +/ 289 /+ friend struct QRegularExpressionMatchPrivate; +/ 290 /+ friend class QRegularExpressionMatchIterator; +/ 291 292 this(ref QRegularExpressionMatchPrivate dd); 293 QExplicitlySharedDataPointer!(QRegularExpressionMatchPrivate) d; 294 mixin(CREATE_CONVENIENCE_WRAPPERS); 295 } 296 297 /+ Q_DECLARE_SHARED(QRegularExpressionMatch) 298 299 #ifndef QT_NO_DEBUG_STREAM 300 Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match); 301 #endif +/ 302 303 extern(C++, "QtPrivate") { 304 extern(C++, class) struct QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel {} 305 } 306 307 struct QRegularExpressionMatchIteratorPrivate; 308 /+ QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchIteratorPrivate, Q_CORE_EXPORT) +/ 309 /// Binding for C++ class [QRegularExpressionMatchIterator](https://doc.qt.io/qt-6/qregularexpressionmatchiterator.html). 310 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QRegularExpressionMatchIterator 311 { 312 public: 313 @disable this(); 314 pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this)))) 315 ref typeof(this) rawConstructor(); 316 static typeof(this) create() 317 { 318 typeof(this) r = typeof(this).init; 319 r.rawConstructor(); 320 return r; 321 } 322 323 ~this(); 324 @disable this(this); 325 this(ref const(QRegularExpressionMatchIterator) iterator); 326 /+ QRegularExpressionMatchIterator(QRegularExpressionMatchIterator &&iterator) = default; +/ 327 /+ref QRegularExpressionMatchIterator operator =(ref const(QRegularExpressionMatchIterator) iterator);+/ 328 /+ QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept 329 { d.swap(iterator.d); return *this; } +/ 330 /+ void swap(QRegularExpressionMatchIterator &other) noexcept { d.swap(other.d); } +/ 331 332 bool isValid() const; 333 334 bool hasNext() const; 335 QRegularExpressionMatch next(); 336 QRegularExpressionMatch peekNext() const; 337 338 QRegularExpression regularExpression() const; 339 QRegularExpression.MatchType matchType() const; 340 QRegularExpression.MatchOptions matchOptions() const; 341 342 private: 343 /+ friend class QRegularExpression; +/ 344 /+ friend Q_CORE_EXPORT QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator); +/ 345 /+ friend QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel end(const QRegularExpressionMatchIterator &) { return {}; } +/ 346 347 this(ref QRegularExpressionMatchIteratorPrivate dd); 348 QExplicitlySharedDataPointer!(QRegularExpressionMatchIteratorPrivate) d; 349 mixin(CREATE_CONVENIENCE_WRAPPERS); 350 } 351 352 extern(C++, "QtPrivate") { 353 354 // support for range-based for loop 355 extern(C++, class) struct QRegularExpressionMatchIteratorRangeBasedForIterator 356 { 357 public: 358 alias value_type = QRegularExpressionMatch; 359 alias difference_type = int; 360 // alias reference_type = ref const(QRegularExpressionMatch); 361 alias pointer_type = const(QRegularExpressionMatch)*; 362 // alias iterator_category = /+ std:: +/forward_iterator_tag; 363 364 @disable this(); 365 /+this() 366 { 367 this.m_atEnd = true; 368 }+/ 369 370 /+/+ explicit +/this(ref const(QRegularExpressionMatchIterator) iterator) 371 { 372 this.m_matchIterator = iterator; 373 this.m_currentMatch = typeof(this.m_currentMatch)(); 374 this.m_atEnd = false; 375 376 ++this; 377 }+/ 378 379 ref const(QRegularExpressionMatch) opUnary(string op)() const if(op == "*") 380 { 381 (mixin(Q_ASSERT_X(q{!m_atEnd},q{ Q_FUNC_INFO},q{ "operator* called on an iterator already at the end"}))); 382 return m_currentMatch; 383 } 384 385 ref QRegularExpressionMatchIteratorRangeBasedForIterator opUnary(string op)() if(op == "++") 386 { 387 (mixin(Q_ASSERT_X(q{!m_atEnd},q{ Q_FUNC_INFO},q{ "operator++ called on an iterator already at the end"}))); 388 if (m_matchIterator.hasNext()) { 389 m_currentMatch = m_matchIterator.next(); 390 } else { 391 m_currentMatch = QRegularExpressionMatch(); 392 m_atEnd = true; 393 } 394 395 return this; 396 } 397 398 /+QRegularExpressionMatchIteratorRangeBasedForIterator operator ++(int) 399 { 400 QRegularExpressionMatchIteratorRangeBasedForIterator i = this; 401 ++this; 402 return i; 403 }+/ 404 405 private: 406 // [input.iterators] imposes operator== on us. Unfortunately, it's not 407 // trivial to implement, so just do the bare minimum to satifisfy 408 // Cpp17EqualityComparable. 409 /+ friend bool operator==(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, 410 const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs) noexcept 411 { 412 return (&lhs == &rhs); 413 } +/ 414 415 /+ friend bool operator!=(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, 416 const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs) noexcept 417 { 418 return !(lhs == rhs); 419 } +/ 420 421 // This is what we really use in a range-based for. 422 /+ friend bool operator==(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, 423 QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel) noexcept 424 { 425 return lhs.m_atEnd; 426 } +/ 427 428 /+ friend bool operator!=(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, 429 QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel) noexcept 430 { 431 return !lhs.m_atEnd; 432 } +/ 433 434 QRegularExpressionMatchIterator m_matchIterator; 435 QRegularExpressionMatch m_currentMatch; 436 bool m_atEnd; 437 } 438 439 } // namespace QtPrivate 440 441 /+ Q_DECLARE_SHARED(QRegularExpressionMatchIterator) +/ 442