Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef nsASCIIMask_h_
7 : #define nsASCIIMask_h_
8 :
9 : #include <array>
10 : #include "mozilla/IndexSequence.h"
11 :
12 : typedef std::array<bool, 128> ASCIIMaskArray;
13 :
14 : namespace mozilla {
15 :
16 : // Boolean arrays, fixed size and filled in at compile time, meant to
17 : // record something about each of the (standard) ASCII characters.
18 : // No extended ASCII for now, there has been no use case.
19 : // If you have loops that go through a string character by character
20 : // and test for equality to a certain set of characters before deciding
21 : // on a course of action, chances are building up one of these arrays
22 : // and using it is going to be faster, especially if the set of
23 : // characters is more than one long, and known at compile time.
24 : class ASCIIMask
25 : {
26 : public:
27 : // Preset masks for some common character groups
28 : // When testing, you must check if the index is < 128 or use IsMasked()
29 : //
30 : // if (someChar < 128 && MaskCRLF()[someChar]) this is \r or \n
31 :
32 : static const ASCIIMaskArray& MaskCRLF();
33 : static const ASCIIMaskArray& Mask0to9();
34 : static const ASCIIMaskArray& MaskCRLFTab();
35 : static const ASCIIMaskArray& MaskWhitespace();
36 :
37 439336 : static MOZ_ALWAYS_INLINE bool IsMasked(const ASCIIMaskArray& aMask, uint32_t aChar)
38 : {
39 439336 : return aChar < 128 && aMask[aChar];
40 : }
41 : };
42 :
43 : // Outside of the preset ones, use these templates to create more masks.
44 : //
45 : // The example creation will look like this:
46 : //
47 : // constexpr bool TestABC(char c) { return c == 'A' || c == 'B' || c == 'C'; }
48 : // constexpr std::array<bool, 128> sABCMask = CreateASCIIMask(TestABC);
49 : // ...
50 : // if (someChar < 128 && sABCMask[someChar]) this is A or B or C
51 :
52 :
53 : namespace details
54 : {
55 : template<typename F, size_t... Indices>
56 : constexpr std::array<bool, 128> CreateASCIIMask(F fun, mozilla::IndexSequence<Indices...>)
57 : {
58 : return {{ fun(Indices)... }};
59 : }
60 : } // namespace details
61 :
62 : template<typename F>
63 : constexpr std::array<bool, 128> CreateASCIIMask(F fun)
64 : {
65 : return details::CreateASCIIMask(fun, mozilla::MakeIndexSequence<128>::Type{});
66 : }
67 :
68 : } // namespace mozilla
69 :
70 : #endif // nsASCIIMask_h_
|