summaryrefslogtreecommitdiffstats
path: root/js/public/RegExpFlags.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/public/RegExpFlags.h')
-rw-r--r--js/public/RegExpFlags.h163
1 files changed, 163 insertions, 0 deletions
diff --git a/js/public/RegExpFlags.h b/js/public/RegExpFlags.h
new file mode 100644
index 0000000000..36a2e76c29
--- /dev/null
+++ b/js/public/RegExpFlags.h
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Regular expression flags. */
+
+#ifndef js_RegExpFlags_h
+#define js_RegExpFlags_h
+
+#include "mozilla/Assertions.h" // MOZ_ASSERT
+#include "mozilla/Attributes.h" // MOZ_IMPLICIT
+
+#include <stdint.h> // uint8_t
+
+namespace JS {
+
+/**
+ * Regular expression flag values, suitable for initializing a collection of
+ * regular expression flags as defined below in |RegExpFlags|. Flags are listed
+ * in alphabetical order by syntax -- /d, /g, /i, /m, /s, /u, /v, /y.
+ */
+class RegExpFlag {
+ // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can
+ // change):
+ //
+ // Flag-bit values appear in XDR and structured clone data formats, so none of
+ // these values can be changed (including to assign values in numerically
+ // ascending order) unless you also add a translation layer.
+
+ public:
+ /**
+ * Add .indices property to the match result, i.e. /d
+ */
+ static constexpr uint8_t HasIndices = 0b0100'0000;
+
+ /**
+ * Act globally and find *all* matches (rather than stopping after just the
+ * first one), i.e. /g.
+ */
+ static constexpr uint8_t Global = 0b0000'0010;
+
+ /**
+ * Interpret regular expression source text case-insensitively by folding
+ * uppercase letters to lowercase, i.e. /i.
+ */
+ static constexpr uint8_t IgnoreCase = 0b0000'0001;
+
+ /** Treat ^ and $ as begin and end of line, i.e. /m. */
+ static constexpr uint8_t Multiline = 0b0000'0100;
+
+ /* Allow . to match newline characters, i.e. /s. */
+ static constexpr uint8_t DotAll = 0b0010'0000;
+
+ /** Use Unicode semantics, i.e. /u. */
+ static constexpr uint8_t Unicode = 0b0001'0000;
+
+ /** Use Unicode Sets semantics, i.e. /v. */
+ static constexpr uint8_t UnicodeSets = 0b1000'0000;
+
+ /** Only match starting from <regular expression>.lastIndex, i.e. /y. */
+ static constexpr uint8_t Sticky = 0b0000'1000;
+
+ /** No regular expression flags. */
+ static constexpr uint8_t NoFlags = 0b0000'0000;
+
+ /** All regular expression flags. */
+ static constexpr uint8_t AllFlags = 0b1111'1111;
+};
+
+/**
+ * A collection of regular expression flags. Individual flag values may be
+ * combined into a collection using bitwise operators.
+ */
+class RegExpFlags {
+ public:
+ using Flag = uint8_t;
+
+ private:
+ Flag flags_;
+
+ public:
+ RegExpFlags() = default;
+
+ MOZ_IMPLICIT RegExpFlags(Flag flags) : flags_(flags) {
+ MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags,
+ "flags must not contain unrecognized flags");
+ }
+
+ RegExpFlags(const RegExpFlags&) = default;
+ RegExpFlags& operator=(const RegExpFlags&) = default;
+
+ bool operator==(const RegExpFlags& other) const {
+ return flags_ == other.flags_;
+ }
+
+ bool operator!=(const RegExpFlags& other) const { return !(*this == other); }
+
+ RegExpFlags& operator&=(const RegExpFlags& rhs) {
+ flags_ &= rhs.flags_;
+ return *this;
+ }
+
+ RegExpFlags& operator|=(const RegExpFlags& rhs) {
+ flags_ |= rhs.flags_;
+ return *this;
+ }
+
+ RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); }
+
+ RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); }
+
+ RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); }
+
+ RegExpFlags operator~() const {
+ return RegExpFlags(~flags_ & RegExpFlag::AllFlags);
+ }
+
+ bool hasIndices() const { return flags_ & RegExpFlag::HasIndices; }
+ bool global() const { return flags_ & RegExpFlag::Global; }
+ bool ignoreCase() const { return flags_ & RegExpFlag::IgnoreCase; }
+ bool multiline() const { return flags_ & RegExpFlag::Multiline; }
+ bool dotAll() const { return flags_ & RegExpFlag::DotAll; }
+ bool unicode() const { return flags_ & RegExpFlag::Unicode; }
+ bool unicodeSets() const { return flags_ & RegExpFlag::UnicodeSets; }
+ bool sticky() const { return flags_ & RegExpFlag::Sticky; }
+
+ explicit operator bool() const { return flags_ != 0; }
+
+ Flag value() const { return flags_; }
+};
+
+inline RegExpFlags& operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) {
+ flags = flags & flag;
+ return flags;
+}
+
+inline RegExpFlags& operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) {
+ flags = flags | flag;
+ return flags;
+}
+
+inline RegExpFlags& operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) {
+ flags = flags ^ flag;
+ return flags;
+}
+
+inline RegExpFlags operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) {
+ RegExpFlags result = lhs;
+ result &= rhs;
+ return lhs;
+}
+
+inline RegExpFlags operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) {
+ RegExpFlags result = lhs;
+ result |= rhs;
+ return result;
+}
+
+} // namespace JS
+
+#endif // js_RegExpFlags_h