/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef ds_Nestable_h #define ds_Nestable_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" namespace js { // A base class for nestable structures. template class MOZ_STACK_CLASS Nestable { Concrete** stack_; Concrete* enclosing_; protected: explicit Nestable(Concrete** stack) : stack_(stack), enclosing_(*stack) { *stack_ = static_cast(this); } // These method are protected. Some derived classes, such as ParseContext, // do not expose the ability to walk the stack. Concrete* enclosing() const { return enclosing_; } template bool */> static Concrete* findNearest(Concrete* it, Predicate predicate) { while (it && !predicate(it)) { it = it->enclosing(); } return it; } template static T* findNearest(Concrete* it) { while (it && !it->template is()) { it = it->enclosing(); } return it ? &it->template as() : nullptr; } template bool */> static T* findNearest(Concrete* it, Predicate predicate) { while (it && (!it->template is() || !predicate(&it->template as()))) { it = it->enclosing(); } return it ? &it->template as() : nullptr; } public: ~Nestable() { MOZ_ASSERT(*stack_ == static_cast(this)); *stack_ = enclosing_; } }; } // namespace js #endif /* ds_Nestable_h */