KiCad PCB EDA Suite
sim_value.cpp
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 (C) 2022 Mikolaj Wielgus
5 * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * https://www.gnu.org/licenses/gpl-3.0.html
20 * or you may search the http://www.gnu.org website for the version 3 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <sim/sim_value.h>
26#include <wx/translation.h>
27#include <ki_exception.h>
28#include <locale_io.h>
29#include <pegtl/contrib/parse_tree.hpp>
30#include <fmt/core.h>
31
32
33#define CALL_INSTANCE( ValueType, Notation, func, ... ) \
34 switch( ValueType ) \
35 { \
36 case SIM_VALUE::TYPE_INT: \
37 switch( Notation ) \
38 { \
39 case NOTATION::SI: \
40 func<SIM_VALUE::TYPE_INT, NOTATION::SI>( __VA_ARGS__ ); \
41 break; \
42 \
43 case NOTATION::SPICE: \
44 func<SIM_VALUE::TYPE_INT, NOTATION::SPICE>( __VA_ARGS__ ); \
45 break; \
46 } \
47 break; \
48 \
49 case SIM_VALUE::TYPE_FLOAT: \
50 switch( Notation ) \
51 { \
52 case NOTATION::SI: \
53 func<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>( __VA_ARGS__ ); \
54 break; \
55 \
56 case NOTATION::SPICE: \
57 func<SIM_VALUE::TYPE_FLOAT, NOTATION::SPICE>( __VA_ARGS__ ); \
58 break; \
59 } \
60 break; \
61 \
62 case SIM_VALUE::TYPE_BOOL: \
63 case SIM_VALUE::TYPE_COMPLEX: \
64 case SIM_VALUE::TYPE_STRING: \
65 case SIM_VALUE::TYPE_BOOL_VECTOR: \
66 case SIM_VALUE::TYPE_INT_VECTOR: \
67 case SIM_VALUE::TYPE_FLOAT_VECTOR: \
68 case SIM_VALUE::TYPE_COMPLEX_VECTOR: \
69 wxFAIL_MSG( "Unhandled SIM_VALUE type" ); \
70 break; \
71 }
72
73
75{
76 using namespace SIM_VALUE_GRAMMAR;
77
78 template <typename Rule>
79 struct numberSelector : std::false_type {};
80
81 // TODO: Reorder. NOTATION should be before TYPE.
82
83 template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE::TYPE_INT>>
84 : std::true_type {};
85 template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE::TYPE_FLOAT>>
86 : std::true_type {};
87 template <> struct numberSelector<intPart> : std::true_type {};
88 template <> struct numberSelector<fracPart> : std::true_type {};
89 template <> struct numberSelector<exponent> : std::true_type {};
90 template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE_INT, NOTATION::SI>>
91 : std::true_type {};
92 template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE_INT, NOTATION::SPICE>>
93 : std::true_type {};
94 template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>>
95 : std::true_type {};
96 template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE_FLOAT, NOTATION::SPICE>>
97 : std::true_type {};
98
100 {
101 bool isOk = true;
102 bool isEmpty = true;
103 std::string significand;
104 std::optional<int64_t> intPart;
105 std::optional<int64_t> fracPart;
106 std::optional<int> exponent;
107 std::optional<int> metricSuffixExponent;
108 };
109
110 PARSE_RESULT Parse( const std::string& aString,
111 NOTATION aNotation = NOTATION::SI,
113
114 int MetricSuffixToExponent( std::string aMetricSuffix, NOTATION aNotation = NOTATION::SI );
115 std::string ExponentToMetricSuffix( double aExponent, int& aReductionExponent,
116 NOTATION aNotation = NOTATION::SI );
117 }
118
119
120template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
121static inline void doIsValid( tao::pegtl::string_input<>& aIn )
122{
123 tao::pegtl::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>>( aIn );
124}
125
126
127bool SIM_VALUE_GRAMMAR::IsValid( const std::string& aString,
128 SIM_VALUE::TYPE aValueType,
129 NOTATION aNotation )
130{
131 tao::pegtl::string_input<> in( aString, "from_content" );
132
133 try
134 {
135 CALL_INSTANCE( aValueType, aNotation, doIsValid, in );
136 }
137 catch( const tao::pegtl::parse_error& )
138 {
139 return false;
140 }
141
142 return true;
143}
144
145
146template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
147static inline std::unique_ptr<tao::pegtl::parse_tree::node> doParse(
148 tao::pegtl::string_input<>& aIn )
149{
150 return tao::pegtl::parse_tree::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>,
152 ( aIn );
153}
154
155
156template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
157static inline void handleNodeForParse( tao::pegtl::parse_tree::node& aNode,
158 SIM_VALUE_PARSER::PARSE_RESULT& aParseResult )
159{
160 if( aNode.is_type<SIM_VALUE_PARSER::significand<ValueType>>() )
161 {
162 aParseResult.significand = aNode.string();
163 aParseResult.isEmpty = false;
164
165 for( const auto& subnode : aNode.children )
166 {
167 if( subnode->is_type<SIM_VALUE_PARSER::intPart>() )
168 aParseResult.intPart = std::stol( subnode->string() );
169 else if( subnode->is_type<SIM_VALUE_PARSER::fracPart>() )
170 aParseResult.fracPart = std::stol( subnode->string() );
171 }
172 }
173 else if( aNode.is_type<SIM_VALUE_PARSER::exponent>() )
174 {
175 aParseResult.exponent = std::stoi( aNode.string() );
176 aParseResult.isEmpty = false;
177 }
179 {
180 aParseResult.metricSuffixExponent =
181 SIM_VALUE_PARSER::MetricSuffixToExponent( aNode.string(), Notation );
182 aParseResult.isEmpty = false;
183 }
184 else
185 wxFAIL_MSG( "Unhandled parse tree node" );
186}
187
188
190 NOTATION aNotation,
191 SIM_VALUE::TYPE aValueType )
192{
193 LOCALE_IO toggle;
194
195 tao::pegtl::string_input<> in( aString, "from_content" );
196 std::unique_ptr<tao::pegtl::parse_tree::node> root;
197 PARSE_RESULT result;
198
199 try
200 {
201 CALL_INSTANCE( aValueType, aNotation, root = doParse, in );
202 }
203 catch( tao::pegtl::parse_error& )
204 {
205 result.isOk = false;
206 return result;
207 }
208
209 wxASSERT( root );
210
211 try
212 {
213 for( const auto& node : root->children )
214 {
215 CALL_INSTANCE( aValueType, aNotation, handleNodeForParse, *node, result );
216 }
217 }
218 catch( const std::invalid_argument& e )
219 {
220 wxFAIL_MSG( fmt::format( "Parsing simulator value failed: {:s}", e.what() ) );
221 result.isOk = false;
222 }
223
224 return result;
225}
226
227
228int SIM_VALUE_PARSER::MetricSuffixToExponent( std::string aMetricSuffix, NOTATION aNotation )
229{
230 switch( aNotation )
231 {
232 case NOTATION::SI:
233 if( aMetricSuffix.empty() )
234 return 0;
235
236 switch( aMetricSuffix[0] )
237 {
238 case 'a': return -18;
239 case 'f': return -15;
240 case 'p': return -12;
241 case 'n': return -9;
242 case 'u': return -6;
243 case 'm': return -3;
244 case 'k':
245 case 'K': return 3;
246 case 'M': return 6;
247 case 'G': return 9;
248 case 'T': return 12;
249 case 'P': return 15;
250 case 'E': return 18;
251 }
252
253 break;
254
255 case NOTATION::SPICE:
256 std::transform( aMetricSuffix.begin(), aMetricSuffix.end(), aMetricSuffix.begin(),
257 ::tolower );
258
259 if( aMetricSuffix == "f" )
260 return -15;
261 else if( aMetricSuffix == "p" )
262 return -12;
263 else if( aMetricSuffix == "n" )
264 return -9;
265 else if( aMetricSuffix == "u" )
266 return -6;
267 else if( aMetricSuffix == "m" )
268 return -3;
269 else if( aMetricSuffix == "" )
270 return 0;
271 else if( aMetricSuffix == "k" )
272 return 3;
273 else if( aMetricSuffix == "meg" )
274 return 6;
275 else if( aMetricSuffix == "g" )
276 return 9;
277 else if( aMetricSuffix == "t" )
278 return 12;
279
280 break;
281 }
282
283 wxFAIL_MSG( fmt::format( "Unknown simulator value suffix: '{:s}'", aMetricSuffix ) );
284 return 0;
285}
286
287
288std::string SIM_VALUE_PARSER::ExponentToMetricSuffix( double aExponent, int& aReductionExponent,
289 NOTATION aNotation )
290{
291 if( aNotation == NOTATION::SI && aExponent >= -18 && aExponent <= -15 )
292 {
293 aReductionExponent = -18;
294 return "a";
295 }
296 else if( aExponent >= -15 && aExponent < -12 )
297 {
298 aReductionExponent = -15;
299 return "f";
300 }
301 else if( aExponent >= -12 && aExponent < -9 )
302 {
303 aReductionExponent = -12;
304 return "p";
305 }
306 else if( aExponent >= -9 && aExponent < -6 )
307 {
308 aReductionExponent = -9;
309 return "n";
310 }
311 else if( aExponent >= -6 && aExponent < -3 )
312 {
313 aReductionExponent = -6;
314 return "u";
315 }
316 else if( aExponent >= -3 && aExponent < 0 )
317 {
318 aReductionExponent = -3;
319 return "m";
320 }
321 else if( aExponent >= 0 && aExponent < 3 )
322 {
323 aReductionExponent = 0;
324 return "";
325 }
326 else if( aExponent >= 3 && aExponent < 6 )
327 {
328 aReductionExponent = 3;
329 return "k";
330 }
331 else if( aExponent >= 6 && aExponent < 9 )
332 {
333 aReductionExponent = 6;
334 return ( aNotation == NOTATION::SI ) ? "M" : "Meg";
335 }
336 else if( aExponent >= 9 && aExponent < 12 )
337 {
338 aReductionExponent = 9;
339 return "G";
340 }
341 else if( aExponent >= 12 && aExponent < 15 )
342 {
343 aReductionExponent = 12;
344 return "T";
345 }
346 else if( aNotation == NOTATION::SI && aExponent >= 15 && aExponent < 18 )
347 {
348 aReductionExponent = 15;
349 return "P";
350 }
351 else if( aNotation == NOTATION::SI && aExponent >= 18 && aExponent <= 21 )
352 {
353 aReductionExponent = 18;
354 return "E";
355 }
356
357 aReductionExponent = 0;
358 return "";
359}
360
361
362std::unique_ptr<SIM_VALUE> SIM_VALUE::Create( TYPE aType, const std::string& aString,
363 NOTATION aNotation )
364{
365 std::unique_ptr<SIM_VALUE> value = SIM_VALUE::Create( aType );
366 value->FromString( aString, aNotation );
367 return value;
368}
369
370
371std::unique_ptr<SIM_VALUE> SIM_VALUE::Create( TYPE aType )
372{
373 switch( aType )
374 {
375 case TYPE_BOOL: return std::make_unique<SIM_VALUE_BOOL>();
376 case TYPE_INT: return std::make_unique<SIM_VALUE_INT>();
377 case TYPE_FLOAT: return std::make_unique<SIM_VALUE_FLOAT>();
378 case TYPE_COMPLEX: return std::make_unique<SIM_VALUE_COMPLEX>();
379 case TYPE_STRING: return std::make_unique<SIM_VALUE_STRING>();
380 case TYPE_BOOL_VECTOR: return std::make_unique<SIM_VALUE_BOOL>();
381 case TYPE_INT_VECTOR: return std::make_unique<SIM_VALUE_INT>();
382 case TYPE_FLOAT_VECTOR: return std::make_unique<SIM_VALUE_FLOAT>();
383 case TYPE_COMPLEX_VECTOR: return std::make_unique<SIM_VALUE_COMPLEX>();
384 }
385
386 wxFAIL_MSG( _( "Unknown SIM_VALUE type" ) );
387 return nullptr;
388}
389
390
391SIM_VALUE& SIM_VALUE::operator=( const std::string& aString )
392{
393 FromString( aString );
394 return *this;
395}
396
397
398bool SIM_VALUE::operator!=( const SIM_VALUE& aOther ) const
399{
400 return !( *this == aOther );
401}
402
403
404template <typename T>
405SIM_VALUE_INST<T>::SIM_VALUE_INST( const T& aValue ) : m_value( aValue )
406{
407}
408
409template SIM_VALUE_BOOL::SIM_VALUE_INST( const bool& aValue );
410template SIM_VALUE_INT::SIM_VALUE_INST( const int& aValue );
411template SIM_VALUE_FLOAT::SIM_VALUE_INST( const double& aValue );
412template SIM_VALUE_COMPLEX::SIM_VALUE_INST( const std::complex<double>& aValue );
413template SIM_VALUE_STRING::SIM_VALUE_INST( const std::string& aValue );
414
415
416template <> SIM_VALUE::TYPE SIM_VALUE_BOOL::GetType() const { return TYPE_BOOL; }
417template <> SIM_VALUE::TYPE SIM_VALUE_INT::GetType() const { return TYPE_INT; }
418template <> SIM_VALUE::TYPE SIM_VALUE_FLOAT::GetType() const { return TYPE_FLOAT; }
419template <> SIM_VALUE::TYPE SIM_VALUE_COMPLEX::GetType() const { return TYPE_FLOAT; }
420template <> SIM_VALUE::TYPE SIM_VALUE_STRING::GetType() const { return TYPE_STRING; }
421// TODO
422/*template <> SIM_VALUE::TYPE SIM_VALUE_BOOL_VECTOR::GetType() const { return TYPE_BOOL; }
423template <> SIM_VALUE::TYPE SIM_VALUE_INT_VECTOR::GetType() const { return TYPE_INT; }
424template <> SIM_VALUE::TYPE SIM_VALUE_FLOAT_VECTOR::GetType() const { return TYPE_FLOAT; }
425template <> SIM_VALUE::TYPE SIM_VALUE_COMPLEX_VECTOR::GetType() const { return TYPE_COMPLEX; }*/
426
427
428template <typename T>
430{
431 return m_value.has_value();
432}
433
434
435template <>
436bool SIM_VALUE_BOOL::FromString( const std::string& aString, NOTATION aNotation )
437{
438 SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
439 m_value = std::nullopt;
440
441 if( !parseResult.isOk )
442 return false;
443
444 if( parseResult.isEmpty )
445 return true;
446
447 if( !parseResult.intPart
448 || ( *parseResult.intPart != 0 && *parseResult.intPart != 1 )
449 || parseResult.fracPart
450 || parseResult.exponent
451 || parseResult.metricSuffixExponent )
452 {
453 return false;
454 }
455
456 m_value = *parseResult.intPart;
457 return true;
458}
459
460
461template <>
462bool SIM_VALUE_INT::FromString( const std::string& aString, NOTATION aNotation )
463{
464 SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
465 m_value = std::nullopt;
466
467 if( !parseResult.isOk )
468 return false;
469
470 if( parseResult.isEmpty )
471 return true;
472
473 if( !parseResult.intPart || ( parseResult.fracPart && *parseResult.fracPart != 0 ) )
474 return false;
475
476 int exponent = parseResult.exponent ? *parseResult.exponent : 0;
477 exponent += parseResult.metricSuffixExponent ? *parseResult.metricSuffixExponent : 0;
478
479 m_value = static_cast<double>( *parseResult.intPart ) * std::pow( 10, exponent );
480 return true;
481}
482
483
484template <>
485bool SIM_VALUE_FLOAT::FromString( const std::string& aString, NOTATION aNotation )
486{
487 wxString buf( aString );
488
489 // Convert any entered decimal point separators to the one our PEGTL grammar expects
490 buf.Replace( wxT( "," ), wxT( "." ) );
491
492 SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( buf.ToStdString(),
493 aNotation );
494 m_value = std::nullopt;
495
496 if( !parseResult.isOk )
497 return false;
498
499 if( parseResult.isEmpty )
500 return true;
501
502 // Single dot should be allowed in fields.
503 // TODO: disallow single dot in models.
504 if( parseResult.significand.empty() || parseResult.significand == "." )
505 return false;
506
507 int exponent = parseResult.exponent ? *parseResult.exponent : 0;
508 exponent += parseResult.metricSuffixExponent ? *parseResult.metricSuffixExponent : 0;
509
510 try
511 {
512 LOCALE_IO toggle;
513
514 m_value = std::stod( parseResult.significand ) * std::pow( 10, exponent );
515 }
516 catch( const std::invalid_argument& )
517 {
518 return false;
519 }
520
521 return true;
522}
523
524
525template <>
526bool SIM_VALUE_COMPLEX::FromString( const std::string& aString, NOTATION aNotation )
527{
528 // TODO
529
530 /*LOCALE_IO toggle;
531
532 double value = 0;
533
534 if( !aString.ToDouble( &value ) )
535 throw KI_PARAM_ERROR( _( "Invalid complex sim value string" ) );
536
537 m_value = value;*/
538 return true;
539}
540
541
542template <>
543bool SIM_VALUE_STRING::FromString( const std::string& aString, NOTATION aNotation )
544{
545 m_value = aString;
546 return true;
547}
548
549
550template <typename T>
551std::string SIM_VALUE_INST<T>::ToString( NOTATION aNotation ) const
552{
553 static_assert( std::is_same<T, std::vector<T>>::value );
554
555 std::string string;
556
557 for( auto it = m_value.cbegin(); it != m_value.cend(); it++ )
558 {
559 string += SIM_VALUE_INST<T>( *it ).ToString();
560 string += ",";
561 }
562
563 return string;
564}
565
566
567template <>
568std::string SIM_VALUE_BOOL::ToString( NOTATION aNotation ) const
569{
570 if( m_value )
571 return fmt::format( "{:d}", *m_value );
572
573 return "";
574}
575
576
577template <>
578std::string SIM_VALUE_INT::ToString( NOTATION aNotation ) const
579{
580 if( m_value )
581 {
582 int value = std::abs( *m_value );
583 int exponent = 0;
584
585 while( value != 0 && value % 1000 == 0 )
586 {
587 exponent += 3;
588 value /= 1000;
589 }
590
591 int dummy = 0;
593 static_cast<double>( exponent ), dummy, aNotation );
594 return fmt::format( "{:d}{:s}", value, metricSuffix );
595 }
596
597 return "";
598}
599
600
601template <>
602std::string SIM_VALUE_FLOAT::ToString( NOTATION aNotation ) const
603{
604 if( m_value )
605 {
606 double exponent = std::log10( std::abs( *m_value ) );
607 int reductionExponent = 0;
608
609 std::string metricSuffix =
610 SIM_VALUE_PARSER::ExponentToMetricSuffix( exponent, reductionExponent, aNotation );
611 double reducedValue = *m_value / std::pow( 10, reductionExponent );
612
613 return fmt::format( "{:g}{}", reducedValue, metricSuffix );
614 }
615 else
616 return "";
617}
618
619
620template <>
621std::string SIM_VALUE_COMPLEX::ToString( NOTATION aNotation ) const
622{
623 if( m_value )
624 return fmt::format( "{:g}+{:g}i", m_value->real(), m_value->imag() );
625
626 return "";
627}
628
629
630template <>
631std::string SIM_VALUE_STRING::ToString( NOTATION aNotation ) const
632{
633 if( m_value )
634 return *m_value;
635
636 return ""; // Empty string is completely equivalent to null string.
637}
638
639
640template <typename T>
642{
643 if( m_value )
644 return fmt::format( "{}", *m_value );
645
646 return "";
647}
648
649
650template <>
651std::string SIM_VALUE_COMPLEX::ToSimpleString() const
652{
653 // TODO
654
655 /*std::string result = "";
656 result << *m_value;
657
658 return result;*/
659 return "";
660}
661
662
663template <typename T>
665{
666 auto other = dynamic_cast<const SIM_VALUE_INST<T>*>( &aOther );
667 m_value = other->m_value;
668 return *this;
669}
670
671
672template <typename T>
673bool SIM_VALUE_INST<T>::operator==( const T& aOther ) const
674{
675 return m_value == aOther;
676}
677
678
679template <>
680bool SIM_VALUE_BOOL::operator==( const bool& aOther ) const
681{
682 // Note that we take nullopt as the same as false here.
683
684 if( !m_value )
685 return false == aOther;
686
687 return m_value == aOther;
688}
689
690
691template bool SIM_VALUE_INT::operator==( const int& aOther ) const;
692template bool SIM_VALUE_FLOAT::operator==( const double& aOther ) const;
693template bool SIM_VALUE_COMPLEX::operator==( const std::complex<double>& aOther ) const;
694template bool SIM_VALUE_STRING::operator==( const std::string& aOther ) const;
695
696
697template <typename T>
698bool SIM_VALUE_INST<T>::operator==( const SIM_VALUE& aOther ) const
699{
700 const SIM_VALUE_INST<T>* otherValue = dynamic_cast<const SIM_VALUE_INST<T>*>( &aOther );
701
702 if( otherValue )
703 return m_value == otherValue->m_value;
704
705 return false;
706}
707
708template <typename T>
710{
711 return SIM_VALUE_INST( aLeft.m_value.value() + aRight.m_value.value() );
712}
713
714template SIM_VALUE_INT operator+( const SIM_VALUE_INT& aLeft,
715 const SIM_VALUE_INT& aRight );
717 const SIM_VALUE_FLOAT& aRight );
718
719
720template <typename T>
722{
723 return SIM_VALUE_INST( aLeft.m_value.value() - aRight.m_value.value() );
724}
725
726template SIM_VALUE_INT operator-( const SIM_VALUE_INT& aLeft,
727 const SIM_VALUE_INT& aRight );
729 const SIM_VALUE_FLOAT& aRight );
730
731
732 template <typename T>
734{
735 return SIM_VALUE_INST( aLeft.m_value.value() * aRight.m_value.value() );
736}
737
738template SIM_VALUE_INT operator*( const SIM_VALUE_INT& aLeft,
739 const SIM_VALUE_INT& aRight );
741 const SIM_VALUE_FLOAT& aRight );
742
743 template <typename T>
745{
746 return SIM_VALUE_INST( aLeft.m_value.value() / aRight.m_value.value() );
747}
748
749template SIM_VALUE_INT operator/( const SIM_VALUE_INT& aLeft,
750 const SIM_VALUE_INT& aRight );
752 const SIM_VALUE_FLOAT& aRight );
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
std::optional< T > m_value
Definition: sim_value.h:145
bool operator==(const T &aOther) const
Definition: sim_value.cpp:673
SIM_VALUE_INST & operator=(const SIM_VALUE &aOther) override
Definition: sim_value.cpp:664
std::string ToString(NOTATION aNotation=NOTATION::SI) const override
Definition: sim_value.cpp:551
bool FromString(const std::string &aString, NOTATION aNotation=NOTATION::SI) override
Definition: sim_value.cpp:436
std::string ToSimpleString() const override
Definition: sim_value.cpp:641
bool HasValue() const override
Definition: sim_value.cpp:429
SIM_VALUE_INST()=default
TYPE GetType() const override
Definition: sim_value.cpp:416
SIM_VALUE & operator=(const std::string &aString)
Definition: sim_value.cpp:391
static std::unique_ptr< SIM_VALUE > Create(TYPE aType, const std::string &aString, NOTATION aNotation=NOTATION::SI)
Definition: sim_value.cpp:362
@ TYPE_BOOL
Definition: sim_value.h:67
@ TYPE_FLOAT_VECTOR
Definition: sim_value.h:75
@ TYPE_BOOL_VECTOR
Definition: sim_value.h:73
@ TYPE_INT
Definition: sim_value.h:68
@ TYPE_FLOAT
Definition: sim_value.h:69
@ TYPE_INT_VECTOR
Definition: sim_value.h:74
@ TYPE_COMPLEX_VECTOR
Definition: sim_value.h:76
@ TYPE_STRING
Definition: sim_value.h:71
@ TYPE_COMPLEX
Definition: sim_value.h:70
bool operator!=(const SIM_VALUE &aOther) const
Definition: sim_value.cpp:398
virtual bool FromString(const std::string &aString, NOTATION aNotation=NOTATION::SI)=0
#define _(s)
bool IsValid(const std::string &aString, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT, NOTATION aNotation=NOTATION::SI)
Definition: sim_value.cpp:127
PARSE_RESULT Parse(const std::string &aString, NOTATION aNotation=NOTATION::SI, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT)
Definition: sim_value.cpp:189
std::string ExponentToMetricSuffix(double aExponent, int &aReductionExponent, NOTATION aNotation=NOTATION::SI)
Definition: sim_value.cpp:288
int MetricSuffixToExponent(std::string aMetricSuffix, NOTATION aNotation=NOTATION::SI)
Definition: sim_value.cpp:228
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:412
SIM_VALUE_INST< T > operator/(const SIM_VALUE_INST< T > &aLeft, const SIM_VALUE_INST< T > &aRight)
Definition: sim_value.cpp:744
SIM_VALUE_INST< T > operator+(const SIM_VALUE_INST< T > &aLeft, const SIM_VALUE_INST< T > &aRight)
Definition: sim_value.cpp:709
SIM_VALUE_INST< T > operator-(const SIM_VALUE_INST< T > &aLeft, const SIM_VALUE_INST< T > &aRight)
Definition: sim_value.cpp:721
SIM_VALUE_INST< T > operator*(const SIM_VALUE_INST< T > &aLeft, const SIM_VALUE_INST< T > &aRight)
Definition: sim_value.cpp:733
static void handleNodeForParse(tao::pegtl::parse_tree::node &aNode, SIM_VALUE_PARSER::PARSE_RESULT &aParseResult)
Definition: sim_value.cpp:157
static std::unique_ptr< tao::pegtl::parse_tree::node > doParse(tao::pegtl::string_input<> &aIn)
Definition: sim_value.cpp:147
#define CALL_INSTANCE(ValueType, Notation, func,...)
Definition: sim_value.cpp:33
static void doIsValid(tao::pegtl::string_input<> &aIn)
Definition: sim_value.cpp:121
std::vector< FAB_LAYER_COLOR > dummy
std::optional< int64_t > fracPart
Definition: sim_value.cpp:105
std::optional< int > metricSuffixExponent
Definition: sim_value.cpp:107
std::optional< int > exponent
Definition: sim_value.cpp:106
std::optional< int64_t > intPart
Definition: sim_value.cpp:104