-
Notifications
You must be signed in to change notification settings - Fork 37
/
circuit.hpp
950 lines (878 loc) · 25.7 KB
/
circuit.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
/* CirKit: A circuit toolkit
* Copyright (C) 2009-2015 University of Bremen
* Copyright (C) 2015-2017 EPFL
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file circuit.hpp
*
* @brief Circuit class
*
* @author Mathias Soeken
* @since 1.0
*/
#ifndef CIRCUIT_HPP
#define CIRCUIT_HPP
#include <map>
#include <memory>
#include <boost/format.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/optional.hpp>
//#include <boost/signals2.hpp>
#include <boost/variant.hpp>
#include <reversible/gate.hpp>
#include <reversible/meta/bus_collection.hpp>
namespace cirkit
{
/**
* @brief Type for determine whether line is constant or not
*
* The following table summarizes the use of constant values
* in circuit representations.
*
* <table border="0">
* <tr>
* <td class="indexkey">Description</td>
* <td class="indexkey">Char representation</td>
* <td class="indexkey">Typed value</td>
* </tr>
* <tr>
* <td class="indexvalue">No constant input line</td>
* <td align="center" class="indexvalue">'-'</td>
* <td class="indexvalue">@code constant() @endcode</td>
* </tr>
* <tr>
* <td class="indexvalue">Constant input line with value 0</td>
* <td align="center" class="indexvalue">'0'</td>
* <td class="indexvalue">@code constant( 0 ) @endcode</td>
* </tr>
* <tr>
* <td class="indexvalue">Constant input line with value 1</td>
* <td align="center" class="indexvalue">'1'</td>
* <td class="indexvalue">@code constant( 1 ) @endcode</td>
* </tr>
* </table>
*
* @section Example
* This example demonstrates how to access the constant values.
* @code
* constant c = // some constant
*
* if ( c ) // checks whether c is set or not
* {
* if ( *c ) // c is checked, checks the value of c
* {
* std::cout << "constant value 1" << std::endl;
* }
* else
* {
* std::cout << "constant value 0" << std::endl;
* }
* }
* else
* {
* std::cout << "no constant value" << std::endl;
* }
* @endcode
*
* @since 1.0
*/
using constant = boost::optional<bool>;
/**
* @brief Represents a circuit
*
* A circuit is represented by a list of gates (type gate::vector)
* and meta information like name, inputs, outputs, constants,
* and garbage.
*
* Via STL like iterators the gates can be accessed and also used
* in STL and STL like algorithms based on the iterator concept.
*
* @section example_circuit_class_1 Example: Creating a circuit with 5 lines
* @code
* #include <reversible/circuit.hpp>
*
* ...
*
* circuit circ( 5 );
* @endcode
*
* @section example_circuit_class_2 Example: Iterate through all gates in a circuit \p circ with iterators
* @code
* for ( circuit::const_iterator itGate = circ.begin(); itGate != circ.end(); ++itGate )
* {
* gate& g = *itGate;
* }
* @endcode
*
* @section example_circuit_class_3 Example: Iterator through all gates in a circuit
* @code
* for ( const auto& g : circ )
* {
* // g can be modified
* }
* @endcode
*
* @since 1.0
*/
class standard_circuit
{
public:
/**
* @brief Default Constructor
*
* Creates an empty circuit with zero lines.
*
* @since 1.0
*/
standard_circuit() : lines( 0 ) {}
/**
* @brief Default Constructor
*
* Creates an empty circuit with \p lines lines.
*
* @param lines Number of lines
*
* @since 1.0
*/
standard_circuit( unsigned lines ) : lines( lines )
{
inputs.resize( lines );
outputs.resize( lines );
for ( unsigned i = 0; i < lines; ++i )
{
inputs[i] = boost::str( boost::format( "i%d" ) % i );
outputs[i] = boost::str( boost::format( "o%d" ) % i );
}
constants.resize( lines, constant() );
garbage.resize( lines, false );
}
/** @cond */
std::vector<std::shared_ptr<gate> > gates;
unsigned lines;
std::vector<std::string> inputs;
std::vector<std::string> outputs;
std::vector<constant> constants;
std::vector<bool> garbage;
std::string name;
bus_collection inputbuses;
bus_collection outputbuses;
bus_collection statesignals;
std::map<const gate*, std::map<std::string, std::string> > annotations;
/** @endcond */
};
class subcircuit;
/**
* @brief Generic circuit
*
* This circuit can be both standard_circuit or a subcircuit.
* In the default case it is considered as standard_circuit with
* no lines.
*
* In the following examples are given how to construct different
* types of circuits.
*
* <b>Empty circuit with no lines</b>
* @code circuit circ; @endcode
*
* <b>Empty circuit with 3 lines</b>
* @code circuit circ( 3 ); @endcode
*
* <b>Sub-circuit from \p circ including gates [2,4)</b>
* @code subcircuit subcirc( circ, 2, 4 ); @endcode
*
* @since 1.0
*/
using circuit_variant = boost::variant<standard_circuit, subcircuit>;
/**
* @brief Represents a sub-circuit
*
* A sub-circuit is a <i>window</i> which can be set
* on top of a standard_circuit. All methods are
* specialized for the sub-circuit. But the gates are
* references to the underlying circuit.
*/
class subcircuit
{
public:
/**
* @brief Default constructor
*
* This constructor creates a sub-circuit from a
* base which is a standard_circuit and a range of gates
* [\p from, \p to). Thus, the gate with index \p to is
* not included.
*
* @param base Underlying circuit
* @param from First gate to be included (starting from 0)
* @param to First gate to be not included anymore
*
* @since 1.0
*/
subcircuit( standard_circuit& base, unsigned from, unsigned to ) : base( &base ), from( from ), to( to ) {}
/**
* @brief Default constructor
*
* Same as other constructor but takes a generic circuit,
* which will get casted to a standard_circuit.
*
* @param base Underlying circuit (has to be standard_circuit in the variant)
* @param from First gate to be included (starting from 0)
* @param to First gate to be not included anymore
*
* @since 1.0
*/
subcircuit( circuit_variant& base, unsigned from, unsigned to ) : base( &boost::get<standard_circuit>( base ) ), from( from ), to( to ) {}
/**
* @brief Default constructor
*
* Same as other constructor but takes a generic circuit,
* which will get casted to a standard_circuit.
*
* @param base Underlying circuit (has to be standard_circuit in the variant)
* @param from First gate to be included (starting from 0)
* @param to First gate to be not included anymore
*
* @since 1.0
*/
subcircuit( const circuit_variant& base, unsigned from, unsigned to ) : base( &boost::get<standard_circuit>( const_cast<circuit_variant&>( base ) ) ), from( from ), to( to ) {}
/** @cond */
standard_circuit* base;
unsigned from;
unsigned to;
};
/**
* @brief Main circuit class
*
* This class represents a circuit and can be used generically for standard circuits and sub circuits.
*
* @since 1.0
*/
class circuit {
public:
/**
* @brief Default constructor
*
* This constructor initializes a standard_circuit with 0 lines, also called an empty circuit.
* Empty circuits are usually used as parameters for parsing functions, optimization algorithms, etc.
*
* @since 1.0
*/
circuit() {}
/**
* @brief Cast Constructor for a standard_circuit
*
* With this constructor the standard_circuit constructor is automatically converted to
* a circuit, e.g. by calling
*
* @code
* circuit circ( 3 );
* @endcode
*
* a circuit with 3 lines is created.
*
* @param std_circ standard_circuit implementation
*
* @since 1.0
*/
circuit( const standard_circuit& std_circ ) : circ( std_circ ) {}
/**
* @brief Cast Constructor for a standard_circuit
*
* With this constructor the standard_circuit constructor is automatically converted to
* a circuit, e.g. by calling
*
* @code
* circuit circ( 3 );
* @endcode
*
* a circuit with 3 lines is created.
*
* @param std_circ standard_circuit implementation
*
* @since 1.0
*/
circuit( standard_circuit& std_circ ) : circ( std_circ ) {}
/**
* @brief Cast Constructor for a subcircuit
*
* This constructor is used, so that subcircuits are detected as circuits in
* algorithms and can passed as circuit parameter to other functions and
* algorithms.
*
* @param sub_circ subcircuit implementation
*
* @since 1.0
*/
circuit( const subcircuit& sub_circ ) : circ( sub_circ ) {}
/**
* @brief Cast Constructor for a subcircuit
*
* This constructor is used, so that subcircuits are detected as circuits in
* algorithms and can passed as circuit parameter to other functions and
* algorithms.
*
* @param sub_circ subcircuit implementation
*
* @since 1.0
*/
circuit( subcircuit& sub_circ ) : circ( sub_circ ) {}
/**
* @brief Copy Constructor
*
* This constructor is used by some algorithms, but should not be used directly.
*
* It copies the underlying circuit, but it does not
* copy the signals, so that this information gets lost.
*
* @param other Circuit to be copied
*
* @since 1.0
*/
circuit( const circuit& other ) : circ( other.circ ) {}
/**
* @brief Mutable iterator for accessing the gates in a circuit
*/
using iterator = boost::indirect_iterator<std::vector<std::shared_ptr<gate>>::iterator>;
/**
* @brief Constant iterator for accessing the gates in a circuit
*/
using const_iterator = boost::indirect_iterator<std::vector<std::shared_ptr<gate>>::const_iterator>;
/**
* @brief Mutable reverse iterator for accessing the gates in a circuit
*/
using reverse_iterator = boost::indirect_iterator<std::vector<std::shared_ptr<gate>>::reverse_iterator>;
/**
* @brief Constant reverse iterator for accessing the gates in a circuit
*/
using const_reverse_iterator = boost::indirect_iterator<std::vector<std::shared_ptr<gate>>::const_reverse_iterator>;
/**
* @brief Returns the number of gates
*
* This method returns the number of gates in the circuit.
*
* @return Number of gates
*
* @since 1.0
*/
unsigned num_gates() const;
/**
* @brief Sets the number of line
*
* This method sets the number of lines of the circuit.
*
* Changing this number will not affect the data in the gates.
* For example: If there is a gate with a control on line 3,
* and the number of lines is reduced to 2 in the circuit, then
* the control is still on line 3 but not visible in this circuit.
*
* So, changing the lines after already adding gates can lead
* to invalid gates.
*
* @param lines Number of lines
*
* @since 1.0
*/
void set_lines( unsigned lines );
/**
* @brief Returns the number of lines
*
* This method returns the number of lines.
*
* @return Number of lines
*
* @since 1.0
*/
unsigned lines() const;
/**
* @brief Constant begin iterator pointing to gates
*
* @return Constant begin iterator
*
* @since 1.0
*/
const_iterator begin() const;
/**
* @brief Constant end iterator pointing to gates
*
* @return Constant end iterator
*
* @since 1.0
*/
const_iterator end() const;
/**
* @brief Mutable begin iterator pointing to gates
*
* @return Mutable begin iterator
*
* @since 1.0
*/
iterator begin();
/**
* @brief Mutable end iterator pointing to gates
*
* @return Mutable end iterator
*
* @since 1.0
*/
iterator end();
/**
* @brief Constant begin reverse iterator pointing to gates
*
* @return Constant begin reverse iterator
*
* @since 1.0
*/
const_reverse_iterator rbegin() const;
/**
* @brief Constant end reverse iterator pointing to gates
*
* @return Constant end reverse iterator
*
* @since 1.0
*/
const_reverse_iterator rend() const;
/**
* @brief Mutable begin reverse iterator pointing to gates
*
* @return Mutable begin reverse iterator
*
* @since 1.0
*/
reverse_iterator rbegin();
/**
* @brief Mutable end reverse iterator pointing to gates
*
* @return Mutable end reverse iterator
*
* @since 1.0
*/
reverse_iterator rend();
/**
* @brief Random access operator for access to gates by index
*
* @param index Index of the gate, starting from 0
* @return constant access to the \p index gate in the circuit
*
* @since 1.1
*/
const gate& operator[]( unsigned index ) const;
/**
* @brief Random access operator for access to gates by index
*
* @param index Index of the gate, starting from 0
* @return mutable access to the \p index gate in the circuit
*
* @since 1.1
*/
gate& operator[]( unsigned index );
/**
* @brief Inserts a gate at the end of the circuit
*
* This method inserts a gate at the end of the circuit.
*
* @return Reference to the newly created empty gate
*
* @since 1.0
*/
gate& append_gate();
/**
* @brief Inserts a gate at the beginning of the circuit
*
* This method inserts a gate at the beginning of the circuit.
*
* @return Reference to the newly created empty gate
*
* @since 1.0
*/
gate& prepend_gate();
/**
* @brief Inserts a gate into the circuit
*
* This method inserts a gate at an arbitrary position in the circuit
*
* @param pos Position where to insert the gate
*
* @return Reference to the newly created empty gate
*
* @since 1.0
*/
gate& insert_gate( unsigned pos );
/**
* @brief Removes a gate at a given index
*
* If the index is not valid, no gate is removed.
*
* @param pos Index
*
* @since 1.0
*/
void remove_gate_at( unsigned pos );
/**
* @brief Sets the input names of the lines in a circuit
*
* This method sets the input names of the lines in a circuit.
* This is useful for functions when writing them to a file,
* printing them, or creating images.
*
* @param inputs Input names
*
* @since 1.0
*/
void set_inputs( const std::vector<std::string>& inputs );
/**
* @brief Returns the input names of the lines in a circuit
*
* This method returns the input names of the lines in a circuit.
* This is useful for functions when writing them to a file,
* printing them, or creating images.
*
* @return Input names
*
* @since 1.0
*/
const std::vector<std::string>& inputs() const;
/**
* @brief Sets the output names of the lines in a circuit
*
* This method sets the output names of the lines in a circuit.
* This is useful for functions when writing them to a file,
* printing them, or creating images.
*
* @param outputs Output names
*
* @since 1.0
*/
void set_outputs( const std::vector<std::string>& outputs );
/**
* @brief Returns the output names of the lines in a circuit
*
* This method returns the output names of the lines in a circuit.
* This is useful for functions when writing them to a file,
* printing them, or creating images.
*
* @return Output names
*
* @since 1.0
*/
const std::vector<std::string>& outputs() const;
/**
* @brief Sets the constant input line specifications
*
* This method sets the constant input line specification.
*
* Lines are by default not constant. If less values are given
* than lines exist, the last ones will be not constant. If more
* values are given than lines exist, they will be truncated.
*
* @sa constant
*
* @param constants Constant Lines
*
* @since 1.0
*/
void set_constants( const std::vector<constant>& constants );
/**
* @brief Returns the constant input line specification
*
* This method returns the constant input line specification.
*
* @return Constant input line specification
*
* @since 1.0
*/
const std::vector<constant>& constants() const;
/**
* @brief Sets whether outputs are garbage or not
*
* If an output is garbage it means, that the resulting
* output value is not necessary for the function.
*
* Lines are by default not garbage. If less values are given
* than lines exist, the last ones will be not garbage. If more
* values are given than lines exist, they will be truncated.
*
* @param garbage Garbage line specification
*
* @since 1.0
*/
void set_garbage( const std::vector<bool>& garbage );
/**
* @brief Returns whether outputs are garbage or not
*
* This method returns the garbage line specification.
*
* @return Garbage output line specification
*
* @since 1.0
*/
const std::vector<bool>& garbage() const;
/**
* @brief Sets a name of the circuit
*
* Sets a name for the circuit which is empty
* initially.
*
* @param name Name
*
* @since 1.0
*/
void set_circuit_name( const std::string& name );
/**
* @brief Returns the name of the circuit
*
* Returns the name of the circuit which is empty
* initially.
*
* @return Name of the circuit
*
* @since 1.0
*/
const std::string& circuit_name() const;
/**
* @brief Constant access to the input buses
*
* This method gives constant access to the input
* buses.
*
* @return Input bus collection
*
* @since 1.1
*/
const bus_collection& inputbuses() const;
/**
* @brief Mutable access to the input buses
*
* This method gives mutable access to the input
* buses.
*
* @return Input bus collection
*
* @since 1.1
*/
bus_collection& inputbuses();
/**
* @brief Constant access to the output buses
*
* This method gives constant access to the output
* buses.
*
* @return Output bus collection
*
* @since 1.1
*/
const bus_collection& outputbuses() const;
/**
* @brief Mutable access to the output buses
*
* This method gives mutable access to the output
* buses.
*
* @return Output bus collection
*
* @since 1.1
*/
bus_collection& outputbuses();
/**
* @brief Constant access to the state signals
*
* This method gives constant access to the state
* signals.
*
* @return State signal collection
*
* @since 1.1
*/
const bus_collection& statesignals() const;
/**
* @brief Mutable access to the state signals
*
* This method gives mutable access to the state
* signals.
*
* @return State signal collection
*
* @since 1.1
*/
bus_collection& statesignals();
/**
* @brief Returns whether the circuit is a sub-circuit or not
*
* Both standard_circuit and subcircuit are used in the context as a circuit
* in other algorithms. To determine what kind of circuit it is, this method
* returns \p true if the circuit is a sub-circuit, \p false otherwise.
*
* @return true, if circuit is a sub-circuit, \p false otherwise
*
* @since 1.0
*/
bool is_subcircuit() const;
/**
* @brief Returns the offset of the circuit (sub-circuit)
*
* For a standard_circuit, the offset is always 0, but for a
* sub-circuit, the offset is the index of the starting gate
* in respect to its base circuit.
*
* @return Offset of the circuit
*
* @since 1.0
*/
unsigned offset() const;
/**
* @brief Adds a module to the circuit
*
* This function adds a module to the circuit. It does
* not create a gate calling the module, but the module
* itself as a reference for further use, e.g. with append_module.
*
* This method uses smart pointer to a circuit wich already
* exists and is managed by another object. If it cannot
* be assured that the module is saved, the method
* add_module(const std::string&, const circuit&) should be used.
*
* @param name Name of the module
* @param module Reference to an existing module
*
* @since 1.1
*/
void add_module( const std::string& name, const std::shared_ptr<circuit>& module );
/**
* @brief Adds a module to the circuit
*
* This function adds a module to the circuit. It does
* not create a gate calling the module, but the module
* itself as a reference for further use, e.g. with append_module.
*
* In this method the module is copied first and thus assured
* that is managed by this circuit.
*
* @param name Name of the module
* @param module Module to be copied
*
* @since 1.1
*/
void add_module( const std::string& name, const circuit& module );
/**
* @brief Returns all modules in the circuit
*
* This method returns a map of all modules, whereby the
* keys are the names of the modules.
*
* @return Map of modules
*
* @since 1.1
*/
const std::map<std::string, std::shared_ptr<circuit> >& modules() const;
/**
* @brief Returns the annotation for one gate and one key
*
* This method returns the value for one particular annotation for
* a given gate. If no annotation with that key exists, the a default
* value is given.
*
* @param g Gate
* @param key Key of the annotation
* @param default_value Default value, in case the key does not exist
*
* @return Value of the annotation or the default value
*
* @since 1.1
*/
const std::string& annotation( const gate& g, const std::string& key, const std::string& default_value = std::string() ) const;
/**
* @brief Returns all annotations for a given gate
*
* This method returns all annotations for a given gate. For the
* purpose of efficiency, this method returns an optional data type
* containing the property map. So, first check whether there are
* items by assierting the optional, and then go through the map
* by dereferencing the optional:
* @code
* boost::optional<const std::map<std::string, std::string>& > annotations = circ.annotations( g );
*
* if ( annotations )
* {
* // annotations exists
* for ( const auto& p : *annotations )
* {
* const std::string& key = p.first;
* const std::string& value = p.second;
* // do something with key and value
* }
* }
* @endcode
*
* @param g Gate
*
* @return Map of annotations encapsulated in an optional
*
* @since 1.1
*/
boost::optional<const std::map<std::string, std::string>& > annotations( const gate& g ) const;
/**
* @brief Annotates a gate
*
* With this method a gate can be annotated using a key and a value.
* If there is an annotation with the same key, it will be overwritten.
*
* @param g Gate
* @param key Key of the annotation
* @param value Value of the annotation
*
* @since 1.1
*/
void annotate( const gate& g, const std::string& key, const std::string& value );
// SIGNALS
/**
* @brief Signal which is emitted after adding a gate
*
* The gate is always empty, since when adding a gate to the
* circuit an empty gate is returned as reference and then
* further processed by functions such as append_toffoli.
*/
//boost::signals2::signal<void(gate&)> gate_added;
/** @cond */
operator circuit_variant&()
{
return circ;
}
operator const circuit_variant&() const
{
return circ;
}
/** @endcond */
private:
/** @cond */
circuit_variant circ;
std::map<std::string, std::shared_ptr<circuit> > _modules;
/** @endcond */
};
}
#endif /* CIRCUIT_HPP */
// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End: