KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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#ifndef LAYER_RANGE_H
23#define LAYER_RANGE_H
24
25
27{
28private:
32
34 {
35 private:
37 int m_stop;
40
41 int next_layer( int aLayer )
42 {
43 if( m_reverse )
44 {
45 if( aLayer == B_Cu )
46 aLayer = m_layer_count == 2 ? F_Cu :
47 static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2;
48 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
49 aLayer = UNDEFINED_LAYER;
50 else if( aLayer == In1_Cu )
51 aLayer = F_Cu;
52 else
53 aLayer = static_cast<int>( aLayer ) - 2;
54 }
55 else
56 {
57 if( aLayer == F_Cu && m_layer_count == 2 )
58 aLayer = B_Cu;
59 else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
60 aLayer = UNDEFINED_LAYER;
61 else if( aLayer == static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2)
62 aLayer = B_Cu;
63 else if( aLayer == F_Cu )
64 aLayer = In1_Cu;
65 else
66 aLayer = static_cast<int>( aLayer ) + 2;
67 }
68
69 return aLayer;
70 }
71
72 public:
73 using iterator_category = std::bidirectional_iterator_tag;
75 using difference_type = std::ptrdiff_t;
78
79 LAYER_RANGE_ITERATOR( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
80 m_current( start ), m_stop( stop ), m_layer_count( layer_count )
81 {
82 if( start & 1 || stop & 1 )
83 throw std::invalid_argument( "Only works for copper layers" );
84
85 if( stop == B_Cu || m_stop >= m_current )
86 m_reverse = false;
87 else
88 m_reverse = true;
89 }
90
91 PCB_LAYER_ID operator*() const { return static_cast<PCB_LAYER_ID>( m_current ); }
92
94 {
96 return *this;
97 }
98
100 {
101 LAYER_RANGE_ITERATOR tmp = *this;
102 ++( *this );
103 return tmp;
104 }
105
106 bool operator==( const LAYER_RANGE_ITERATOR& other ) const
107 {
108 return m_current == other.m_current;
109 }
110
111 bool operator!=( const LAYER_RANGE_ITERATOR& other ) const { return !( *this == other ); }
112 };
113
114public:
115 LAYER_RANGE( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
116 m_start( start ), m_stop( stop ), m_layer_count( layer_count )
117 {
118 if( start & 1 || stop & 1 )
119 throw std::invalid_argument( "Only works for copper layers" );
120 }
121
123 m_layer_count ); }
124
126 {
128 return ++it;
129 }
130
131 static bool Contains( int aStart_layer, int aEnd_layer, int aTest_layer )
132 {
133 // B_Cu is the lowest copper layer for Z order copper layers
134 // F_cu = top, B_Cu = bottom
135 // So set the distance from top for B_Cu to INT_MAX
136 if( aTest_layer == B_Cu )
137 aTest_layer = INT_MAX;
138
139 if( aStart_layer == B_Cu )
140 aStart_layer = INT_MAX;
141
142 if( aEnd_layer == B_Cu )
143 aEnd_layer = INT_MAX;
144
145 if( aStart_layer > aEnd_layer )
146 std::swap( aStart_layer, aEnd_layer );
147
148 return aTest_layer >= aStart_layer && aTest_layer <= aEnd_layer;
149 }
150
151 bool Contains( int aTest_layer )
152 {
153 return Contains( m_start, m_stop, aTest_layer );
154 }
155
156 size_t size() const
157 {
158 if( m_start == B_Cu )
159 return m_layer_count;
160 else
161 return ( m_stop - m_start ) / 2 + 1;
162 }
163};
164
165#endif // LAYER_RANGE_H
PCB_LAYER_ID operator*() const
Definition: layer_range.h:91
bool operator==(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:106
LAYER_RANGE_ITERATOR operator++(int)
Definition: layer_range.h:99
bool operator!=(const LAYER_RANGE_ITERATOR &other) const
Definition: layer_range.h:111
LAYER_RANGE_ITERATOR & operator++()
Definition: layer_range.h:93
std::bidirectional_iterator_tag iterator_category
Definition: layer_range.h:73
LAYER_RANGE_ITERATOR(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition: layer_range.h:79
int m_layer_count
Definition: layer_range.h:31
PCB_LAYER_ID m_stop
Definition: layer_range.h:30
static bool Contains(int aStart_layer, int aEnd_layer, int aTest_layer)
Definition: layer_range.h:131
LAYER_RANGE_ITERATOR end() const
Definition: layer_range.h:125
size_t size() const
Definition: layer_range.h:156
LAYER_RANGE_ITERATOR begin() const
Definition: layer_range.h:122
PCB_LAYER_ID m_start
Definition: layer_range.h:29
LAYER_RANGE(PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count)
Definition: layer_range.h:115
bool Contains(int aTest_layer)
Definition: layer_range.h:151
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