Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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 ds_Nestable_h
8 : #define ds_Nestable_h
9 :
10 : namespace js {
11 :
12 : // A base class for nestable structures.
13 : template <typename Concrete>
14 : class MOZ_STACK_CLASS Nestable
15 : {
16 : Concrete** stack_;
17 : Concrete* enclosing_;
18 :
19 : protected:
20 97672 : explicit Nestable(Concrete** stack)
21 : : stack_(stack),
22 97672 : enclosing_(*stack)
23 : {
24 97672 : *stack_ = static_cast<Concrete*>(this);
25 97672 : }
26 :
27 : // These method are protected. Some derived classes, such as ParseContext,
28 : // do not expose the ability to walk the stack.
29 145029 : Concrete* enclosing() const {
30 145029 : return enclosing_;
31 : }
32 :
33 : template <typename Predicate /* (Concrete*) -> bool */>
34 8992 : static Concrete* findNearest(Concrete* it, Predicate predicate) {
35 11192 : while (it && !predicate(it))
36 2200 : it = it->enclosing();
37 6792 : return it;
38 : }
39 :
40 : template <typename T>
41 7249 : static T* findNearest(Concrete* it) {
42 7389 : while (it && !it->template is<T>())
43 140 : it = it->enclosing();
44 7109 : return it ? &it->template as<T>() : nullptr;
45 : }
46 :
47 : template <typename T, typename Predicate /* (T*) -> bool */>
48 484 : static T* findNearest(Concrete* it, Predicate predicate) {
49 489 : while (it && (!it->template is<T>() || !predicate(&it->template as<T>())))
50 5 : it = it->enclosing();
51 479 : return it ? &it->template as<T>() : nullptr;
52 : }
53 :
54 : public:
55 97680 : ~Nestable() {
56 97680 : MOZ_ASSERT(*stack_ == static_cast<Concrete*>(this));
57 97680 : *stack_ = enclosing_;
58 97680 : }
59 : };
60 :
61 : } // namespace js
62 :
63 : #endif /* ds_Nestable_h */
|