KiCad PCB EDA Suite
Loading...
Searching...
No Matches
conn_keys.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
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <kiid.h>
23#include <wx/string.h>
24#include <cstdint>
25#include <limits>
26#include <map>
27#include <optional>
28#include <stdexcept>
29#include <string>
30#include <unordered_map>
31#include <variant>
32#include <vector>
33
39namespace SCH_CONNECTIVITY
40{
41using INST_ID = uint32_t;
42using NAME_ID = uint32_t;
43using NODE_ID = uint32_t;
44using SCREEN_ID = uint64_t;
45
47constexpr uint32_t INVALID_ID = std::numeric_limits<uint32_t>::max();
48
54enum class KIND : uint8_t
55{
58};
59
63enum class SCOPE : uint8_t
64{
67 PORT
68};
69
77{
80 bool operator==( const ITEM_KEY& ) const = default;
81};
82
87{
90 bool operator==( const RECORD_KEY& ) const = default;
91};
92
97{
100 bool operator==( const RECORD_NODE& ) const = default;
101};
102
110{
111 SCOPE scope = SCOPE::SHEET;
115
116 bool operator==( const NAME_KEY& aOther ) const
117 {
118 return scope == aOther.scope && text == aOther.text && ( scope == SCOPE::GLOBAL || inst == aOther.inst )
119 && ( scope != SCOPE::PORT || kind == aOther.kind );
120 }
121};
122
127{
129 uint32_t leaf = 0;
130 bool operator==( const SLOT_KEY& ) const = default;
131};
132
136using NODE_KEY = std::variant<RECORD_NODE, NAME_KEY, SLOT_KEY>;
137
146{
147public:
148 SESSION_KEYS() = default;
149 SESSION_KEYS( const SESSION_KEYS& ) = delete;
151
152 INST_ID InternInstance( const KIID_PATH& aPath ) { return m_instances.Intern( aPath ); }
153 NAME_ID InternName( const wxString& aText ) { return m_names.Intern( { aText, aText.utf8_string() } ); }
155 std::optional<NAME_ID> FindName( const wxString& aText ) const
156 {
157 return m_names.Find( { {}, aText.utf8_string() } );
158 }
159
160 std::optional<INST_ID> FindInstance( const KIID_PATH& aPath ) const { return m_instances.Find( aPath ); }
161
162 const KIID_PATH& Instance( INST_ID aId ) const { return m_instances.Value( aId ); }
163 const wxString& Name( NAME_ID aId ) const { return m_names.Value( aId ).text; }
164 const NODE_KEY& Node( NODE_ID aId ) const { return m_nodes.Value( aId ); }
165 size_t NodeCount() const { return m_nodes.Size(); }
166 bool NameLess( NAME_ID aLeft, NAME_ID aRight ) const
167 {
168 return m_names.Value( aLeft ).utf8 < m_names.Value( aRight ).utf8;
169 }
170
171 bool Less( const ITEM_KEY& aLeft, const ITEM_KEY& aRight ) const;
172 bool Less( const RECORD_KEY& aLeft, const RECORD_KEY& aRight ) const;
173 bool Less( const RECORD_NODE& aLeft, const RECORD_NODE& aRight ) const;
174 bool Less( const NAME_KEY& aLeft, const NAME_KEY& aRight ) const;
175 bool Less( const SLOT_KEY& aLeft, const SLOT_KEY& aRight ) const;
176 bool Less( const NODE_KEY& aLeft, const NODE_KEY& aRight ) const;
177
178private:
179 template <typename VALUE, typename MAP = std::map<VALUE, uint32_t>>
181 {
182 public:
183 INTERN_TABLE() = default;
184 INTERN_TABLE( const INTERN_TABLE& ) = delete;
186
187 uint32_t Intern( const VALUE& aValue )
188 {
189 // Size never exceeds INVALID_ID, so a full table proposes exactly INVALID_ID
190 auto [it, inserted] = m_ids.try_emplace( aValue, static_cast<uint32_t>( m_values.size() ) );
191
192 if( !inserted )
193 return it->second;
194
195 try
196 {
197 if( it->second == INVALID_ID )
198 throw std::overflow_error( "Connectivity intern IDs exhausted" );
199
200 m_values.push_back( &it->first );
201 }
202 catch( ... )
203 {
204 m_ids.erase( it );
205 throw;
206 }
207
208 return it->second;
209 }
210
211 std::optional<uint32_t> Find( const VALUE& aValue ) const
212 {
213 const auto found = m_ids.find( aValue );
214 return found == m_ids.end() ? std::nullopt : std::optional<uint32_t>( found->second );
215 }
216
217 const VALUE& Value( uint32_t aId ) const { return *m_values.at( aId ); }
218 size_t Size() const { return m_values.size(); }
219
220 private:
221 MAP m_ids;
222 // Both ordered and unordered maps keep key addresses stable during growth.
223 std::vector<const VALUE*> m_values;
224 };
225
227 {
228 wxString text;
229 std::string utf8;
230 bool operator<( const INTERNED_NAME& aOther ) const { return utf8 < aOther.utf8; }
231 };
232
234 {
235 size_t operator()( const NODE_KEY& aKey ) const;
236 };
237
240
242};
243
246{
248 bool operator()( NAME_ID aLeft, NAME_ID aRight ) const { return keys->NameLess( aLeft, aRight ); }
249};
250
255{
257
258 template <typename KEY>
259 bool operator()( const KEY& aLeft, const KEY& aRight ) const
260 {
261 return keys.Less( aLeft, aRight );
262 }
263};
264} // namespace SCH_CONNECTIVITY
Definition kiid.h:46
std::vector< const VALUE * > m_values
Definition conn_keys.h:223
uint32_t Intern(const VALUE &aValue)
Definition conn_keys.h:187
INTERN_TABLE(const INTERN_TABLE &)=delete
const VALUE & Value(uint32_t aId) const
Definition conn_keys.h:217
INTERN_TABLE & operator=(const INTERN_TABLE &)=delete
std::optional< uint32_t > Find(const VALUE &aValue) const
Definition conn_keys.h:211
Session IDs are dense handles, never a canonical ordering.
Definition conn_keys.h:146
std::optional< NAME_ID > FindName(const wxString &aText) const
Definition conn_keys.h:155
const NODE_KEY & Node(NODE_ID aId) const
Definition conn_keys.h:164
SESSION_KEYS & operator=(const SESSION_KEYS &)=delete
const wxString & Name(NAME_ID aId) const
Definition conn_keys.h:163
SESSION_KEYS(const SESSION_KEYS &)=delete
INTERN_TABLE< KIID_PATH > m_instances
Definition conn_keys.h:238
const KIID_PATH & Instance(INST_ID aId) const
Definition conn_keys.h:162
INST_ID InternInstance(const KIID_PATH &aPath)
Definition conn_keys.h:152
INTERN_TABLE< NODE_KEY, std::unordered_map< NODE_KEY, uint32_t, NODE_HASH > > m_nodes
Definition conn_keys.h:241
NAME_ID InternName(const wxString &aText)
Definition conn_keys.h:153
std::optional< INST_ID > FindInstance(const KIID_PATH &aPath) const
Definition conn_keys.h:160
bool Less(const ITEM_KEY &aLeft, const ITEM_KEY &aRight) const
Definition conn_keys.cpp:98
INTERN_TABLE< INTERNED_NAME > m_names
Definition conn_keys.h:239
bool NameLess(NAME_ID aLeft, NAME_ID aRight) const
Definition conn_keys.h:166
NODE_ID InternNode(NODE_KEY aKey)
Definition conn_keys.cpp:28
KIID niluuid(0)
Value keys and the key session of the schematic connectivity engine.
std::variant< RECORD_NODE, NAME_KEY, SLOT_KEY > NODE_KEY
Any node of the union-find graph.
Definition conn_keys.h:136
SCOPE
The namespace in which a NAME_KEY joins records.
Definition conn_keys.h:64
@ SHEET
Joins names in one instance only.
Definition conn_keys.h:65
uint32_t INST_ID
Session handle of a sheet instance KIID_PATH.
Definition conn_keys.h:41
uint32_t NAME_ID
Session handle of a name, ordered by UTF-8 value through NAME_LESS.
Definition conn_keys.h:42
uint64_t SCREEN_ID
Process-local SCH_SCREEN::ConnectivityId(), never a file UUID.
Definition conn_keys.h:44
uint32_t NODE_ID
Session handle of a NODE_KEY graph node.
Definition conn_keys.h:43
KIND
The electrical type of a record or component.
Definition conn_keys.h:55
constexpr uint32_t INVALID_ID
Marks an unset handle.
Definition conn_keys.h:47
One item or pin in one sheet instance.
Definition conn_keys.h:77
KIID item
The item or pin KIID.
Definition conn_keys.h:78
INST_ID inst
The sheet instance that shows the item.
Definition conn_keys.h:79
bool operator==(const ITEM_KEY &) const =default
Orders keys by value through SESSION_KEYS::Less().
Definition conn_keys.h:255
bool operator()(const KEY &aLeft, const KEY &aRight) const
Definition conn_keys.h:259
const SESSION_KEYS & keys
Definition conn_keys.h:256
The graph node of one name in one scope.
Definition conn_keys.h:110
KIND kind
The record kind. Only PORT compares it.
Definition conn_keys.h:114
INST_ID inst
The sheet instance, or the child instance of a sheet pin for PORT.
Definition conn_keys.h:112
NAME_ID text
The resolved name.
Definition conn_keys.h:113
bool operator==(const NAME_KEY &aOther) const
Definition conn_keys.h:116
Orders name handles by UTF-8 value.
Definition conn_keys.h:246
const SESSION_KEYS * keys
Definition conn_keys.h:247
bool operator()(NAME_ID aLeft, NAME_ID aRight) const
Definition conn_keys.h:248
One island in one sheet instance.
Definition conn_keys.h:87
INST_ID inst
The sheet instance of the record.
Definition conn_keys.h:88
bool operator==(const RECORD_KEY &) const =default
KIID anchor
ISLAND::anchor, the smallest item KIID in the island.
Definition conn_keys.h:89
The graph node of one island record.
Definition conn_keys.h:97
KIND kind
The kind of the record, which selects its stratum.
Definition conn_keys.h:99
bool operator==(const RECORD_NODE &) const =default
bool operator<(const INTERNED_NAME &aOther) const
Definition conn_keys.h:230
size_t operator()(const NODE_KEY &aKey) const
Definition conn_keys.cpp:54
One member position of a bus.
Definition conn_keys.h:127
bool operator==(const SLOT_KEY &) const =default
ITEM_KEY bundleDriver
The source item of the claim that defines the leaf order.
Definition conn_keys.h:128
uint32_t leaf
The index into BUS_SCHEMA::leaves of that claim.
Definition conn_keys.h:129
@ VALUE
Field Value of part, i.e. "3.3K".