1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_REGEXP_REGEXP_FLAGS_H_
6#define V8_REGEXP_REGEXP_FLAGS_H_
7
8#include "src/base/flags.h"
9#include "src/base/optional.h"
10
11namespace v8 {
12namespace internal {
13
14// TODO(jgruber,pthier): Decouple more parts of the codebase from
15// JSRegExp::Flags. Consider removing JSRegExp::Flags.
16
17// Order is important! Sorted in alphabetic order by the flag char. Note this
18// means that flag bits are shuffled. Take care to keep them contiguous when
19// adding/removing flags.
20#define REGEXP_FLAG_LIST(V)                      \
21  V(has_indices, HasIndices, hasIndices, 'd', 7) \
22  V(global, Global, global, 'g', 0)              \
23  V(ignore_case, IgnoreCase, ignoreCase, 'i', 1) \
24  V(linear, Linear, linear, 'l', 6)              \
25  V(multiline, Multiline, multiline, 'm', 2)     \
26  V(dot_all, DotAll, dotAll, 's', 5)             \
27  V(unicode, Unicode, unicode, 'u', 4)           \
28  V(sticky, Sticky, sticky, 'y', 3)
29
30#define V(Lower, Camel, LowerCamel, Char, Bit) k##Camel = 1 << Bit,
31enum class RegExpFlag { REGEXP_FLAG_LIST(V) };
32#undef V
33
34#define V(...) +1
35constexpr int kRegExpFlagCount = REGEXP_FLAG_LIST(V);
36#undef V
37
38// Assert alpha-sorted chars.
39#define V(Lower, Camel, LowerCamel, Char, Bit) < Char) && (Char
40static_assert((('a' - 1) REGEXP_FLAG_LIST(V) <= 'z'), "alpha-sort chars");
41#undef V
42
43// Assert contiguous indices.
44#define V(Lower, Camel, LowerCamel, Char, Bit) | (1 << Bit)
45static_assert(((1 << kRegExpFlagCount) - 1) == (0 REGEXP_FLAG_LIST(V)),
46              "contiguous bits");
47#undef V
48
49using RegExpFlags = base::Flags<RegExpFlag>;
50DEFINE_OPERATORS_FOR_FLAGS(RegExpFlags)
51
52#define V(Lower, Camel, ...)                \
53  constexpr bool Is##Camel(RegExpFlags f) { \
54    return (f & RegExpFlag::k##Camel) != 0; \
55  }
56REGEXP_FLAG_LIST(V)
57#undef V
58
59// clang-format off
60#define V(Lower, Camel, LowerCamel, Char, Bit) \
61  c == Char ? RegExpFlag::k##Camel :
62constexpr base::Optional<RegExpFlag> TryRegExpFlagFromChar(char c) {
63  return REGEXP_FLAG_LIST(V) base::Optional<RegExpFlag>{};
64}
65#undef V
66// clang-format on
67
68}  // namespace internal
69}  // namespace v8
70
71#endif  // V8_REGEXP_REGEXP_FLAGS_H_
72