Source code

Revision control

Other Tools

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 ds_Nestable_h
8
#define ds_Nestable_h
9
10
#include "mozilla/Assertions.h"
11
#include "mozilla/Attributes.h"
12
13
namespace js {
14
15
// A base class for nestable structures.
16
template <typename Concrete>
17
class MOZ_STACK_CLASS Nestable {
18
Concrete** stack_;
19
Concrete* enclosing_;
20
21
protected:
22
explicit Nestable(Concrete** stack) : stack_(stack), enclosing_(*stack) {
23
*stack_ = static_cast<Concrete*>(this);
24
}
25
26
// These method are protected. Some derived classes, such as ParseContext,
27
// do not expose the ability to walk the stack.
28
Concrete* enclosing() const { return enclosing_; }
29
30
template <typename Predicate /* (Concrete*) -> bool */>
31
static Concrete* findNearest(Concrete* it, Predicate predicate) {
32
while (it && !predicate(it)) {
33
it = it->enclosing();
34
}
35
return it;
36
}
37
38
template <typename T>
39
static T* findNearest(Concrete* it) {
40
while (it && !it->template is<T>()) {
41
it = it->enclosing();
42
}
43
return it ? &it->template as<T>() : nullptr;
44
}
45
46
template <typename T, typename Predicate /* (T*) -> bool */>
47
static T* findNearest(Concrete* it, Predicate predicate) {
48
while (it && (!it->template is<T>() || !predicate(&it->template as<T>()))) {
49
it = it->enclosing();
50
}
51
return it ? &it->template as<T>() : nullptr;
52
}
53
54
public:
55
~Nestable() {
56
MOZ_ASSERT(*stack_ == static_cast<Concrete*>(this));
57
*stack_ = enclosing_;
58
}
59
};
60
61
} // namespace js
62
63
#endif /* ds_Nestable_h */