/src/mozilla-central/xpcom/string/nsASCIIMask.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef nsASCIIMask_h_ |
8 | | #define nsASCIIMask_h_ |
9 | | |
10 | | #include <array> |
11 | | #include <utility> |
12 | | |
13 | | #include "mozilla/Attributes.h" |
14 | | |
15 | | typedef std::array<bool, 128> ASCIIMaskArray; |
16 | | |
17 | | namespace mozilla { |
18 | | |
19 | | // Boolean arrays, fixed size and filled in at compile time, meant to |
20 | | // record something about each of the (standard) ASCII characters. |
21 | | // No extended ASCII for now, there has been no use case. |
22 | | // If you have loops that go through a string character by character |
23 | | // and test for equality to a certain set of characters before deciding |
24 | | // on a course of action, chances are building up one of these arrays |
25 | | // and using it is going to be faster, especially if the set of |
26 | | // characters is more than one long, and known at compile time. |
27 | | class ASCIIMask |
28 | | { |
29 | | public: |
30 | | // Preset masks for some common character groups |
31 | | // When testing, you must check if the index is < 128 or use IsMasked() |
32 | | // |
33 | | // if (someChar < 128 && MaskCRLF()[someChar]) this is \r or \n |
34 | | |
35 | | static const ASCIIMaskArray& MaskCRLF(); |
36 | | static const ASCIIMaskArray& Mask0to9(); |
37 | | static const ASCIIMaskArray& MaskCRLFTab(); |
38 | | static const ASCIIMaskArray& MaskWhitespace(); |
39 | | |
40 | | static MOZ_ALWAYS_INLINE bool IsMasked(const ASCIIMaskArray& aMask, uint32_t aChar) |
41 | 103M | { |
42 | 103M | return aChar < 128 && aMask[aChar]; |
43 | 103M | } |
44 | | }; |
45 | | |
46 | | // Outside of the preset ones, use these templates to create more masks. |
47 | | // |
48 | | // The example creation will look like this: |
49 | | // |
50 | | // constexpr bool TestABC(char c) { return c == 'A' || c == 'B' || c == 'C'; } |
51 | | // constexpr std::array<bool, 128> sABCMask = CreateASCIIMask(TestABC); |
52 | | // ... |
53 | | // if (someChar < 128 && sABCMask[someChar]) this is A or B or C |
54 | | |
55 | | |
56 | | namespace details |
57 | | { |
58 | | template<typename F, size_t... Indices> |
59 | | constexpr std::array<bool, 128> CreateASCIIMask(F fun, std::index_sequence<Indices...>) |
60 | 0 | { |
61 | 0 | return {{ fun(Indices)... }}; |
62 | 0 | } |
63 | | } // namespace details |
64 | | |
65 | | template<typename F> |
66 | | constexpr std::array<bool, 128> CreateASCIIMask(F fun) |
67 | 0 | { |
68 | 0 | return details::CreateASCIIMask(fun, std::make_index_sequence<128>{}); |
69 | 0 | } |
70 | | |
71 | | } // namespace mozilla |
72 | | |
73 | | #endif // nsASCIIMask_h_ |