1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef TypedElementDescendantIterator_h 27#define TypedElementDescendantIterator_h 28 29#include "ElementIterator.h" 30 31namespace WebCore { 32 33template <typename ElementType> 34class TypedElementDescendantIterator : public ElementIterator<ElementType> { 35public: 36 TypedElementDescendantIterator(const ContainerNode& root); 37 TypedElementDescendantIterator(const ContainerNode& root, ElementType* current); 38 TypedElementDescendantIterator& operator++(); 39}; 40 41template <typename ElementType> 42class TypedElementDescendantConstIterator : public ElementConstIterator<ElementType> { 43public: 44 TypedElementDescendantConstIterator(const ContainerNode& root); 45 TypedElementDescendantConstIterator(const ContainerNode& root, const ElementType* current); 46 TypedElementDescendantConstIterator& operator++(); 47}; 48 49template <typename ElementType> 50class TypedElementDescendantIteratorAdapter { 51public: 52 TypedElementDescendantIteratorAdapter(ContainerNode& root); 53 TypedElementDescendantIterator<ElementType> begin(); 54 TypedElementDescendantIterator<ElementType> end(); 55 TypedElementDescendantIterator<ElementType> beginAt(ElementType&); 56 TypedElementDescendantIterator<ElementType> from(Element&); 57 58 ElementType* first(); 59 ElementType* last(); 60 61private: 62 ContainerNode& m_root; 63}; 64 65template <typename ElementType> 66class TypedElementDescendantConstIteratorAdapter { 67public: 68 TypedElementDescendantConstIteratorAdapter(const ContainerNode& root); 69 TypedElementDescendantConstIterator<ElementType> begin() const; 70 TypedElementDescendantConstIterator<ElementType> end() const; 71 TypedElementDescendantConstIterator<ElementType> beginAt(const ElementType&) const; 72 TypedElementDescendantConstIterator<ElementType> from(const Element&) const; 73 74 const ElementType* first() const; 75 const ElementType* last() const; 76 77private: 78 const ContainerNode& m_root; 79}; 80 81template <typename ElementType> TypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode&); 82template <typename ElementType> TypedElementDescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode&); 83 84// TypedElementDescendantIterator 85 86template <typename ElementType> 87inline TypedElementDescendantIterator<ElementType>::TypedElementDescendantIterator(const ContainerNode& root) 88 : ElementIterator<ElementType>(&root) 89{ 90} 91 92template <typename ElementType> 93inline TypedElementDescendantIterator<ElementType>::TypedElementDescendantIterator(const ContainerNode& root, ElementType* current) 94 : ElementIterator<ElementType>(&root, current) 95{ 96} 97 98template <typename ElementType> 99inline TypedElementDescendantIterator<ElementType>& TypedElementDescendantIterator<ElementType>::operator++() 100{ 101 return static_cast<TypedElementDescendantIterator<ElementType>&>(ElementIterator<ElementType>::traverseNext()); 102} 103 104// TypedElementDescendantConstIterator 105 106template <typename ElementType> 107inline TypedElementDescendantConstIterator<ElementType>::TypedElementDescendantConstIterator(const ContainerNode& root) 108 : ElementConstIterator<ElementType>(&root) 109 110{ 111} 112 113template <typename ElementType> 114inline TypedElementDescendantConstIterator<ElementType>::TypedElementDescendantConstIterator(const ContainerNode& root, const ElementType* current) 115 : ElementConstIterator<ElementType>(&root, current) 116{ 117} 118 119template <typename ElementType> 120inline TypedElementDescendantConstIterator<ElementType>& TypedElementDescendantConstIterator<ElementType>::operator++() 121{ 122 return static_cast<TypedElementDescendantConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseNext()); 123} 124 125// TypedElementDescendantIteratorAdapter 126 127template <typename ElementType> 128inline TypedElementDescendantIteratorAdapter<ElementType>::TypedElementDescendantIteratorAdapter(ContainerNode& root) 129 : m_root(root) 130{ 131} 132 133template <typename ElementType> 134inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::begin() 135{ 136 return TypedElementDescendantIterator<ElementType>(m_root, Traversal<ElementType>::firstWithin(&m_root)); 137} 138 139template <typename ElementType> 140inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::end() 141{ 142 return TypedElementDescendantIterator<ElementType>(m_root); 143} 144 145template <typename ElementType> 146inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::beginAt(ElementType& descendant) 147{ 148 ASSERT(descendant.isDescendantOf(&m_root)); 149 return TypedElementDescendantIterator<ElementType>(m_root, &descendant); 150} 151 152template <typename ElementType> 153inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::from(Element& descendant) 154{ 155 ASSERT(descendant.isDescendantOf(&m_root)); 156 if (isElementOfType<const ElementType>(descendant)) 157 return TypedElementDescendantIterator<ElementType>(m_root, static_cast<ElementType*>(&descendant)); 158 ElementType* next = Traversal<ElementType>::next(&m_root, &descendant); 159 return TypedElementDescendantIterator<ElementType>(m_root, next); 160} 161 162template <typename ElementType> 163inline ElementType* TypedElementDescendantIteratorAdapter<ElementType>::first() 164{ 165 return Traversal<ElementType>::firstWithin(&m_root); 166} 167 168template <typename ElementType> 169inline ElementType* TypedElementDescendantIteratorAdapter<ElementType>::last() 170{ 171 return Traversal<ElementType>::lastWithin(&m_root); 172} 173 174// TypedElementDescendantConstIteratorAdapter 175 176template <typename ElementType> 177inline TypedElementDescendantConstIteratorAdapter<ElementType>::TypedElementDescendantConstIteratorAdapter(const ContainerNode& root) 178 : m_root(root) 179{ 180} 181 182template <typename ElementType> 183inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::begin() const 184{ 185 return TypedElementDescendantConstIterator<ElementType>(m_root, Traversal<ElementType>::firstWithin(&m_root)); 186} 187 188template <typename ElementType> 189inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::end() const 190{ 191 return TypedElementDescendantConstIterator<ElementType>(m_root); 192} 193 194template <typename ElementType> 195inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::beginAt(const ElementType& descendant) const 196{ 197 ASSERT(descendant.isDescendantOf(&m_root)); 198 return TypedElementDescendantConstIterator<ElementType>(m_root, &descendant); 199} 200 201template <typename ElementType> 202inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::from(const Element& descendant) const 203{ 204 ASSERT(descendant.isDescendantOf(&m_root)); 205 if (isElementOfType<const ElementType>(descendant)) 206 return TypedElementDescendantConstIterator<ElementType>(m_root, static_cast<const ElementType*>(&descendant)); 207 const ElementType* next = Traversal<ElementType>::next(&m_root, &descendant); 208 return TypedElementDescendantConstIterator<ElementType>(m_root, next); 209} 210 211template <typename ElementType> 212inline const ElementType* TypedElementDescendantConstIteratorAdapter<ElementType>::first() const 213{ 214 return Traversal<ElementType>::firstWithin(&m_root); 215} 216 217template <typename ElementType> 218inline const ElementType* TypedElementDescendantConstIteratorAdapter<ElementType>::last() const 219{ 220 return Traversal<ElementType>::lastWithin(&m_root); 221} 222 223// Standalone functions 224 225template <typename ElementType> 226inline TypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& root) 227{ 228 return TypedElementDescendantIteratorAdapter<ElementType>(root); 229} 230 231template <typename ElementType> 232inline TypedElementDescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode& root) 233{ 234 return TypedElementDescendantConstIteratorAdapter<ElementType>(root); 235} 236 237} 238 239#endif 240