Merge mozilla-central to autoland. a=merge CLOSED TREE
[gecko.git] / js / public / RegExpFlags.h
blobe4663786fcfaa65aa7ce21fb38ef21511d385006
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Regular expression flags. */
9 #ifndef js_RegExpFlags_h
10 #define js_RegExpFlags_h
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
13 #include "mozilla/Attributes.h" // MOZ_IMPLICIT
15 #include <ostream> // ostream
16 #include <stdint.h> // uint8_t
18 namespace JS {
20 /**
21 * Regular expression flag values, suitable for initializing a collection of
22 * regular expression flags as defined below in |RegExpFlags|. Flags are listed
23 * in alphabetical order by syntax -- /d, /g, /i, /m, /s, /u, /v, /y.
25 class RegExpFlag {
26 // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can
27 // change):
29 // Flag-bit values appear in XDR and structured clone data formats, so none of
30 // these values can be changed (including to assign values in numerically
31 // ascending order) unless you also add a translation layer.
33 public:
34 /**
35 * Add .indices property to the match result, i.e. /d
37 static constexpr uint8_t HasIndices = 0b0100'0000;
39 /**
40 * Act globally and find *all* matches (rather than stopping after just the
41 * first one), i.e. /g.
43 static constexpr uint8_t Global = 0b0000'0010;
45 /**
46 * Interpret regular expression source text case-insensitively by folding
47 * uppercase letters to lowercase, i.e. /i.
49 static constexpr uint8_t IgnoreCase = 0b0000'0001;
51 /** Treat ^ and $ as begin and end of line, i.e. /m. */
52 static constexpr uint8_t Multiline = 0b0000'0100;
54 /* Allow . to match newline characters, i.e. /s. */
55 static constexpr uint8_t DotAll = 0b0010'0000;
57 /** Use Unicode semantics, i.e. /u. */
58 static constexpr uint8_t Unicode = 0b0001'0000;
60 /** Use Unicode Sets semantics, i.e. /v. */
61 static constexpr uint8_t UnicodeSets = 0b1000'0000;
63 /** Only match starting from <regular expression>.lastIndex, i.e. /y. */
64 static constexpr uint8_t Sticky = 0b0000'1000;
66 /** No regular expression flags. */
67 static constexpr uint8_t NoFlags = 0b0000'0000;
69 /** All regular expression flags. */
70 static constexpr uint8_t AllFlags = 0b1111'1111;
73 /**
74 * A collection of regular expression flags. Individual flag values may be
75 * combined into a collection using bitwise operators.
77 class RegExpFlags {
78 public:
79 using Flag = uint8_t;
81 private:
82 Flag flags_;
84 public:
85 RegExpFlags() = default;
87 MOZ_IMPLICIT RegExpFlags(Flag flags) : flags_(flags) {
88 MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags,
89 "flags must not contain unrecognized flags");
92 RegExpFlags(const RegExpFlags&) = default;
93 RegExpFlags& operator=(const RegExpFlags&) = default;
95 bool operator==(const RegExpFlags& other) const {
96 return flags_ == other.flags_;
99 bool operator!=(const RegExpFlags& other) const { return !(*this == other); }
101 RegExpFlags& operator&=(const RegExpFlags& rhs) {
102 flags_ &= rhs.flags_;
103 return *this;
106 RegExpFlags& operator|=(const RegExpFlags& rhs) {
107 flags_ |= rhs.flags_;
108 return *this;
111 RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); }
113 RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); }
115 RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); }
117 RegExpFlags operator~() const {
118 return RegExpFlags(~flags_ & RegExpFlag::AllFlags);
121 bool hasIndices() const { return flags_ & RegExpFlag::HasIndices; }
122 bool global() const { return flags_ & RegExpFlag::Global; }
123 bool ignoreCase() const { return flags_ & RegExpFlag::IgnoreCase; }
124 bool multiline() const { return flags_ & RegExpFlag::Multiline; }
125 bool dotAll() const { return flags_ & RegExpFlag::DotAll; }
126 bool unicode() const { return flags_ & RegExpFlag::Unicode; }
127 bool unicodeSets() const { return flags_ & RegExpFlag::UnicodeSets; }
128 bool sticky() const { return flags_ & RegExpFlag::Sticky; }
130 explicit operator bool() const { return flags_ != 0; }
132 Flag value() const { return flags_; }
133 constexpr operator Flag() const { return flags_; }
135 void set(Flag flags, bool value) {
136 if (value) {
137 flags_ |= flags;
138 } else {
139 flags_ &= ~flags;
144 inline RegExpFlags& operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) {
145 flags = flags & flag;
146 return flags;
149 inline RegExpFlags& operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) {
150 flags = flags | flag;
151 return flags;
154 inline RegExpFlags& operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) {
155 flags = flags ^ flag;
156 return flags;
159 inline RegExpFlags operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) {
160 RegExpFlags result = lhs;
161 result &= rhs;
162 return lhs;
165 inline RegExpFlags operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) {
166 RegExpFlags result = lhs;
167 result |= rhs;
168 return result;
171 inline bool MaybeParseRegExpFlag(char c, RegExpFlags::Flag* flag) {
172 switch (c) {
173 case 'd':
174 *flag = RegExpFlag::HasIndices;
175 return true;
176 case 'g':
177 *flag = RegExpFlag::Global;
178 return true;
179 case 'i':
180 *flag = RegExpFlag::IgnoreCase;
181 return true;
182 case 'm':
183 *flag = RegExpFlag::Multiline;
184 return true;
185 case 's':
186 *flag = RegExpFlag::DotAll;
187 return true;
188 case 'u':
189 *flag = RegExpFlag::Unicode;
190 return true;
191 case 'v':
192 *flag = RegExpFlag::UnicodeSets;
193 return true;
194 case 'y':
195 *flag = RegExpFlag::Sticky;
196 return true;
197 default:
198 return false;
202 std::ostream& operator<<(std::ostream& os, RegExpFlags flags);
204 } // namespace JS
206 #endif // js_RegExpFlags_h