In a previous post, I wrote Let's code with good visibility using std :: map type.
If you have more than a certain amount of embedded environment (eg board such as Raspberry Pi or Zynq), you can use g ++ and there should be no problem using STL. And you can write programs using STL containers. I think that STL should be actively used for making a version that works correctly when developing on a PC (I am worried about the implementation of C ++ of some commercial compilers, and STL using that compiler I think the situation is different from the old days when I was worried about the implementation of. At that time, I heard that I was asked to rewrite the code written using STL to non-STL code.) .. The external specifications of STL are clear, and it is easy for multiple members to share a common understanding. As much as I enjoyed using STL, I avoid the effort to fully clarify the specifications and test the algorithms of other parts.
If the final implementation is a PC, you could leave it as STL, or you might choose to leave it as STL in some embedded environments. In this article, for those who still can't use the STL for their final implementation, I suggest using the STL when developing code that works correctly on the PC version by showing that the C ++ source can be automatically generated. It is something to do.
The following Python script reads the mapping data of std :: map <std :: string, int> in the withMap.cpp file and generates a sequence of if () else if () statements without using STL. is.
intoElseif.py
# -*- coding: utf-8 -*-
def parseMap(name):
u"""
std::map<std::string, int>Read atmomicNumbers.
Read the map key and value and assign them to the Python dictionary.
"""
d = {}
for line in open(name, "rt"):
oline = line.strip().replace(",", " ")
if len(oline) > 1 and oline[-1] == ",":
oline = oline[:-1]
f = oline.split()
if len(f) == 4 and f[0] == "{":
d[int(f[2])] = f[1]
return d
if __name__ == "__main__":
u"""
C based on the read dictionary/C++Generate a language if else if statement.
"""
d = parseMap(name="withMap.cpp")
keys = d.keys()
keys.sort()
k = keys[0]
print """if(strcmp(instr, %s) == 0){
r = %s;
}""" % (d[k], k),
for i in range(1, len(keys)):
k = keys[i]
print """else if(strcmp(instr, %s) == 0){
r = %s;
}""" % (d[k], k),
C ++ file containing std :: map type data of input data
withMap.cpp
#include <iostream>
#include <string>
#include <map>
/**Map type container that associates atomic numbers with element symbols
*Initialization is carried out at the same time as the declaration.
*(Only up to Ne in the second cycle is described.)
*/
std::map<std::string, int> atmomicNumbers = {
{ "H", 1 },
{ "He", 2 },
{ "Li", 3 },
{ "Be", 4 },
{ "B", 5 },
{ "C", 6 },
{ "N", 7 },
{ "O", 8 },
{ "F", 9 },
{ "Ne", 10 }
};
int main(int argc, char* argv[]){
std::string symbol = "Be";
std::cout << symbol << " " << atmomicNumbers[symbol] << std::endl;
}
Execution result
generated.cpp
if(strcmp(instr, "H") == 0){
r = 1;
} else if(strcmp(instr, "He") == 0){
r = 2;
} else if(strcmp(instr, "Li") == 0){
r = 3;
} else if(strcmp(instr, "Be") == 0){
r = 4;
} else if(strcmp(instr, "B") == 0){
r = 5;
} else if(strcmp(instr, "C") == 0){
r = 6;
} else if(strcmp(instr, "N") == 0){
r = 7;
} else if(strcmp(instr, "O") == 0){
r = 8;
} else if(strcmp(instr, "F") == 0){
r = 9;
} else if(strcmp(instr, "Ne") == 0){
r = 10;
}
In this way, it is easy to automatically generate a part of a program from a part of regular data. Therefore, we insist on ensuring the health of the program using a clear data format.
If you write a program using std :: map, the effect of increasing data will be
{ "Ne", 10 }
All you have to do is add the following lines, eliminating the need to change the code elsewhere.
I think that it is first to secure a mechanism that can guarantee that it works correctly, and then to secure the performance (processing speed, program size) on the implementation.
In the above example, without using std :: map
python
char* [] atomicSymbols = {
"H", "He",
"Li", "Be", "B", "c", "N", "O", "F", "Ne"
}
It is also possible to process using the array. However, here we are using the std :: map <std :: string, int>
type to suggest using a standard library for the logic that associates keys with values.
Generating parts of a program using a scripting language has long been used by some. When writing a lot of similar contents with only the data replaced, a part of the program was automatically generated based on the data. The data is updated frequently, so it may not be possible to write it by hand once. Such an approach can be used for any language. For example, Ratfor, a FORTRAN extension language, used a preprocessor to hide the shortcomings of the FORTRAN language specification. I think that improving the visibility of the processing being done is to ensure the soundness of the program at an early stage.
Postscript: "Programming Style" Chapter 9 Notation "9.5 Program to write a program" has a name and It is designed to generate an error message based on a header file that contains comments. In that book, a perl script automatically converts it. In this way, the scripting language can be used to accelerate development in the C / C ++ language.
python
enum {
Eperm, /* Permission denied */
Eio, /* I/O error */
Efile, /* File does not exist */
Emem, /* Memory limit reached */
Espace, /* Out of file space */
Egreg /* It's all Greg's fault */
};
There is an example of generating the following declaration from.
python
char *errs[] = {
"Permission denied", /* Eperm */
"I/O error", /* Eio */
"File does not exist", /* Efile */
"Memory limit reached", /* Emem */
"Out of file space", /* Espace */
"It's all Greg's fault", /* Egreg */
};
Recommended Posts