comparison enigma/machine.cpp @ 13:b9d124a15926

To improve cache performance, the enigma machine rotors are now stored together with the reflector in a vector.
author Brian Neal <bgneal@gmail.com>
date Mon, 02 Jul 2012 19:14:36 -0500
parents da231533c5c7
children 919b7a0d1802
comparison
equal deleted inserted replaced
12:424111a36ed7 13:b9d124a15926
16 16
17 enigma_machine::enigma_machine( 17 enigma_machine::enigma_machine(
18 const rotor_vector& rv, 18 const rotor_vector& rv,
19 std::shared_ptr<rotor> reflector, 19 std::shared_ptr<rotor> reflector,
20 const plugboard& pb) 20 const plugboard& pb)
21 : rotors(rv), 21 : rotors(),
22 reflector(reflector),
23 pb(pb) 22 pb(pb)
24 { 23 {
24 rotors.push_back(*reflector);
25 for (const auto& r : rv)
26 {
27 rotors.push_back(*r);
28 }
25 rotor_count_check(); 29 rotor_count_check();
26 } 30 }
27 31
28 //////////////////////////////////////////////////////////////////////////////// 32 ////////////////////////////////////////////////////////////////////////////////
29 33
30 enigma_machine::enigma_machine( 34 enigma_machine::enigma_machine(
31 const rotor_vector& rv, 35 const rotor_vector& rv,
32 std::shared_ptr<rotor> reflector) 36 std::shared_ptr<rotor> reflector)
33 : rotors(rv), 37 : rotors(),
34 reflector(reflector),
35 pb() 38 pb()
36 { 39 {
40 rotors.push_back(*reflector);
41 for (const auto& r : rv)
42 {
43 rotors.push_back(*r);
44 }
37 rotor_count_check(); 45 rotor_count_check();
38 } 46 }
39 47
40 //////////////////////////////////////////////////////////////////////////////// 48 ////////////////////////////////////////////////////////////////////////////////
41 49
43 const std::vector<std::string>& rotor_types, 51 const std::vector<std::string>& rotor_types,
44 const std::vector<int>& ring_settings, 52 const std::vector<int>& ring_settings,
45 const std::string& reflector_name, 53 const std::string& reflector_name,
46 const std::string& plugboard_settings) 54 const std::string& plugboard_settings)
47 : rotors(), 55 : rotors(),
48 reflector(create_reflector(reflector_name.c_str())),
49 pb(plugboard_settings) 56 pb(plugboard_settings)
50 { 57 {
58 const auto ukw(create_reflector(reflector_name.c_str()));
59 rotors.push_back(*ukw);
51 for (const auto& name : rotor_types) 60 for (const auto& name : rotor_types)
52 { 61 {
53 rotors.push_back(create_rotor(name.c_str())); 62 const auto r(create_rotor(name.c_str()));
63 rotors.push_back(*r);
54 } 64 }
55 rotor_count_check(); 65 rotor_count_check();
56 66
57 // if ring settings are supplied, there has to be one for each rotor 67 // if ring settings are supplied, there has to be one for each rotor
58 if (!ring_settings.empty()) 68 if (!ring_settings.empty())
59 { 69 {
60 if (rotors.size() != ring_settings.size()) 70 if (rotors.size() - 1 != ring_settings.size())
61 { 71 {
62 throw enigma_machine_error("rotor/ring setting count mismatch"); 72 throw enigma_machine_error("rotor/ring setting count mismatch");
63 } 73 }
64 74
65 for (std::size_t i = 0; i < rotors.size(); ++i) 75 for (std::size_t i = 1; i < rotors.size(); ++i)
66 { 76 {
67 rotors[i]->set_ring_setting(ring_settings[i]); 77 rotors[i].set_ring_setting(ring_settings[i - 1]);
68 } 78 }
69 } 79 }
70 } 80 }
71 81
72 //////////////////////////////////////////////////////////////////////////////// 82 ////////////////////////////////////////////////////////////////////////////////
73 83
74 void enigma_machine::rotor_count_check() 84 void enigma_machine::rotor_count_check()
75 { 85 {
76 if (rotors.size() != 3 && rotors.size() != 4) 86 // the first rotor is actually the reflector; so we should have a total
87 // of 4 or 5 rotors
88 if (rotors.size() != 4 && rotors.size() != 5)
77 { 89 {
78 throw enigma_machine_error("rotor count"); 90 throw enigma_machine_error("rotor count");
79 } 91 }
80 92
81 if (rotors.size() == 3) 93 if (rotors.size() == 4)
82 { 94 {
83 r_rotor = rotors[2].get(); 95 r_rotor = &rotors[3];
84 m_rotor = rotors[1].get(); 96 m_rotor = &rotors[2];
85 l_rotor = rotors[0].get(); 97 l_rotor = &rotors[1];
86 } 98 }
87 else 99 else
88 { 100 {
89 r_rotor = rotors[3].get(); 101 r_rotor = &rotors[4];
90 m_rotor = rotors[2].get(); 102 m_rotor = &rotors[3];
91 l_rotor = rotors[1].get(); 103 l_rotor = &rotors[2];
92 } 104 }
93 } 105 }
94 106
95 //////////////////////////////////////////////////////////////////////////////// 107 ////////////////////////////////////////////////////////////////////////////////
96 108
97 std::string enigma_machine::str(bool army) const 109 std::string enigma_machine::str(bool army) const
98 { 110 {
99 std::ostringstream os; 111 std::ostringstream os;
100 112
101 os << reflector->name() << ' '; 113 os << rotors[0].name() << ' ';
102 114
103 for (const auto& r : rotors) 115 for (std::size_t i = 1; i < rotors.size(); ++i)
104 { 116 {
105 os << r->name() << '/' << r->get_ring_setting() << ' '; 117 os << rotors[i].name() << '/' << rotors[i].get_ring_setting() << ' ';
106 } 118 }
107 119
108 os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str()); 120 os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str());
109 121
110 return os.str(); 122 return os.str();