KiCad PCB EDA Suite
Loading...
Searching...
No Matches
layer_range.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <layer_ids.h>
21
22#include <algorithm>
23
24#ifndef LAYER_RANGE_H
25#define LAYER_RANGE_H
26
27
29{
30private:
34
36 {
37 private:
39 int m_stop;
42
43 int next_layer( int aLayer )
44 {
45 if( m_reverse )
46 {
47 if( aLayer == B_Cu )
48 aLayer = m_layer_count == 2 ? F_Cu :
49 static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2;
50 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
51 aLayer = UNDEFINED_LAYER;
52 else if( aLayer == In1_Cu )
53 aLayer = F_Cu;
54 else
55 aLayer = static_cast<int>( aLayer ) - 2;
56 }
57 else
58 {
59 if( aLayer == F_Cu && m_layer_count == 2 )
60 aLayer = B_Cu;
61 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
62 aLayer = UNDEFINED_LAYER;
63 else if( aLayer == static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2)
64 aLayer = B_Cu;
65 else if( aLayer == F_Cu )
66 aLayer = In1_Cu;
67 else
68 aLayer = static_cast<int>( aLayer ) + 2;
69 }
70
71 return aLayer;
72 }
73
74 public:
75 using iterator_category = std::bidirectional_iterator_tag;
77 using difference_type = std::ptrdiff_t;
80
81 LAYER_RANGE_ITERATOR( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
82 m_current( start ), m_stop( stop ), m_layer_count( layer_count )
83 {
84 if( start & 1 || stop & 1 )
85 throw std::invalid_argument( "Only works for copper layers" );
86
87 if( stop == B_Cu || m_stop >= m_current )
88 m_reverse = false;
89 else
90 m_reverse = true;
91 }
92
93 PCB_LAYER_ID operator*() const { return static_cast<PCB_LAYER_ID>( m_current ); }
94
96 {
98 return *this;
99 }
100
102 {
103 LAYER_RANGE_ITERATOR tmp = *this;
104 ++( *this );
105 return tmp;
106 }
107
108 bool operator==( const LAYER_RANGE_ITERATOR& other ) const
109 {
110 return m_current == other.m_current;
111 }
112
113 bool operator!=( const LAYER_RANGE_ITERATOR& other ) const { return !( *this == other ); }
114 };
115
116public:
117 LAYER_RANGE( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
118 m_start( start ), m_stop( stop ), m_layer_count( std::max( layer_count, 2 ) )
119 {
120 if( start & 1 || stop & 1 )
121 throw std::invalid_argument( "Only works for copper layers" );
122 }
123
126
128 {
130 return ++it;
131 }
132
133 static bool Contains( int aStart_layer, int aEnd_layer, int aTest_layer )
134 {
135 // B_Cu is the lowest copper layer for Z order copper layers
136 // F_cu = top, B_Cu = bottom
137 // So set the distance from top for B_Cu to INT_MAX
138 if( aTest_layer == B_Cu )
139 aTest_layer = INT_MAX;
140
141 if( aStart_layer == B_Cu )
142 aStart_layer = INT_MAX;
143
144 if( aEnd_layer == B_Cu )
145 aEnd_layer = INT_MAX;
146
147 if( aStart_layer > aEnd_layer )
148 std::swap( aStart_layer, aEnd_layer );
149
150 return aTest_layer >= aStart_layer && aTest_layer <= aEnd_layer;
151 }
152
153 bool Contains( int aTest_layer )
154 {
155 return Contains( m_start, m_stop, aTest_layer );
156 }
157
158 size_t size() const
159 {
160 if( m_start == B_Cu )
161 return m_layer_count;
162 else
163 return ( m_stop - m_start ) / 2 + 1;
164 }
165};
166
167#endif // LAYER_RANGE_H
PCB_LAYER_ID operator*() const
Definition layer_range.h:93
bool operator==(const LAYER_RANGE_ITERATOR &other) const
LAYER_RANGE_ITERATOR operator++(int)
bool operator!=(const LAYER_RANGE_ITERATOR &other) const
LAYER_RANGE_ITERATOR & operator++()
Definition layer_range.h:95
std::bidirectional_iterator_tag iterator_category
Definition layer_range.h:75
LAYER_RANGE_ITERATOR(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition layer_range.h:81
int m_layer_count
Definition layer_range.h:33
PCB_LAYER_ID m_stop
Definition layer_range.h:32
static bool Contains(int aStart_layer, int aEnd_layer, int aTest_layer)
LAYER_RANGE_ITERATOR end() const
size_t size() const
LAYER_RANGE_ITERATOR begin() const
PCB_LAYER_ID m_start
Definition layer_range.h:31
LAYER_RANGE(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
bool Contains(int aTest_layer)
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ B_Cu
Definition layer_ids.h:65
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ In1_Cu
Definition layer_ids.h:66
@ F_Cu
Definition layer_ids.h:64
STL namespace.