1 /* 2 * KiRouter - a push-and-(sometimes-)shove PCB router 3 * 4 * Copyright (C) 2013-2014 CERN 5 * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> 7 * 8 * This program is free software: you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation, either version 3 of the License, or (at your 11 * option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #ifndef __PNS_ITEMSET_H 23 #define __PNS_ITEMSET_H 24 25 #include <vector> 26 #include <core/kicad_algo.h> 27 #include "pns_item.h" 28 29 namespace PNS { 30 31 /** 32 * Hold a list of board items, that can be filtered against net, kinds, layers, etc. 33 */ 34 class LINE; 35 36 class ITEM_SET 37 { 38 public: 39 struct ENTRY 40 { 41 ENTRY( ITEM* aItem, bool aOwned = false ) : itemENTRY42 item( aItem ), 43 owned( aOwned ) 44 {} 45 ENTRYENTRY46 ENTRY( const ENTRY& aOther ) 47 { 48 owned = aOther.owned; 49 50 if( aOther.owned ) 51 item = aOther.item->Clone(); 52 else 53 item = aOther.item; 54 } 55 ~ENTRYENTRY56 ~ENTRY() 57 { 58 if( owned ) 59 delete item; 60 } 61 62 bool operator==( const ENTRY& b ) const 63 { 64 return item == b.item; 65 } 66 67 bool operator<( const ENTRY& b ) const 68 { 69 return item < b.item; 70 } 71 72 ENTRY& operator=( const ENTRY& aOther ) 73 { 74 owned = aOther.owned; 75 76 if( aOther.owned ) 77 item = aOther.item->Clone(); 78 else 79 item = aOther.item; 80 81 return *this; 82 } 83 84 operator ITEM* () const 85 { 86 return item; 87 } 88 89 ITEM *item; 90 bool owned; 91 }; 92 93 typedef std::vector<ENTRY> ENTRIES; 94 95 ITEM_SET( ITEM* aInitialItem = nullptr, bool aBecomeOwner = false ) 96 { 97 if( aInitialItem ) 98 m_items.emplace_back( ENTRY( aInitialItem, aBecomeOwner ) ); 99 } 100 ITEM_SET(const ITEM_SET & aOther)101 ITEM_SET( const ITEM_SET& aOther ) 102 { 103 m_items = aOther.m_items; 104 } 105 106 ~ITEM_SET(); 107 108 ITEM_SET& operator=( const ITEM_SET& aOther ) 109 { 110 m_items = aOther.m_items; 111 return *this; 112 } 113 114 int Count( int aKindMask = -1 ) const 115 { 116 int n = 0; 117 118 if( aKindMask == -1 || aKindMask == ITEM::ANY_T ) 119 return static_cast<int>( m_items.size() ); 120 121 for( ITEM* item : m_items ) 122 { 123 if( item->Kind() & aKindMask ) 124 n++; 125 } 126 127 return n; 128 } 129 Empty()130 bool Empty() const 131 { 132 return m_items.empty(); 133 } 134 Items()135 ENTRIES& Items() { return m_items; } CItems()136 const ENTRIES& CItems() const { return m_items; } 137 138 ITEM_SET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false ); 139 ITEM_SET& FilterKinds( int aKindMask, bool aInvert = false ); 140 ITEM_SET& FilterNet( int aNet, bool aInvert = false ); 141 ITEM_SET& FilterMarker( int aMarker, bool aInvert = false ); 142 143 ITEM_SET& ExcludeLayers( int aStart, int aEnd = -1 ) 144 { 145 return FilterLayers( aStart, aEnd, true ); 146 } 147 ExcludeKinds(int aKindMask)148 ITEM_SET& ExcludeKinds( int aKindMask ) 149 { 150 return FilterKinds( aKindMask, true ); 151 } 152 ExcludeNet(int aNet)153 ITEM_SET& ExcludeNet( int aNet ) 154 { 155 return FilterNet( aNet, true ); 156 } 157 158 ITEM_SET& ExcludeItem( const ITEM* aItem ); 159 Size()160 int Size() const 161 { 162 return static_cast<int>( m_items.size() ); 163 } 164 165 void Add( const LINE& aLine ); 166 void Prepend( const LINE& aLine ); 167 168 ITEM* operator[]( size_t aIndex ) const 169 { 170 return m_items[aIndex].item; 171 } 172 begin()173 ENTRIES::iterator begin() { return m_items.begin(); } end()174 ENTRIES::iterator end() { return m_items.end(); } cbegin()175 ENTRIES::const_iterator cbegin() const { return m_items.cbegin(); } cend()176 ENTRIES::const_iterator cend() const { return m_items.cend(); } 177 178 void Add( ITEM* aItem, bool aBecomeOwner = false ) 179 { 180 m_items.emplace_back( ENTRY( aItem, aBecomeOwner ) ); 181 } 182 183 void Prepend( ITEM* aItem, bool aBecomeOwner = false ) 184 { 185 m_items.emplace( m_items.begin(), ENTRY( aItem, aBecomeOwner ) ); 186 } 187 Clear()188 void Clear() 189 { 190 m_items.clear(); 191 } 192 Contains(ITEM * aItem)193 bool Contains( ITEM* aItem ) const 194 { 195 const ENTRY ent( aItem ); 196 return alg::contains( m_items, ent ); 197 } 198 Erase(ITEM * aItem)199 void Erase( ITEM* aItem ) 200 { 201 ENTRY ent( aItem ); 202 ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent ); 203 204 if( f != m_items.end() ) 205 m_items.erase( f ); 206 } 207 208 template<class T> 209 T* FindByKind( ITEM::PnsKind kind, int index = 0 ) 210 { 211 int n = 0; 212 213 for( const ITEM* item : m_items ) 214 { 215 if( item->OfKind( kind ) ) 216 { 217 if( index == n ) 218 return static_cast<T*>( item ); 219 else 220 n++; 221 } 222 } 223 224 return nullptr; 225 } 226 227 private: 228 ENTRIES m_items; 229 }; 230 231 } 232 233 #endif 234