#include <string>
#include <iostream>
#include <vector>
#include <array>
#include <complex>
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
std::array<e, N-1> buffer; //get buffer
in >> buffer[0]; //skips whitespace
if (N>2)
in.read(&buffer[1], N-2); //read the rest
if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
in.setstate(in.rdstate() | std::ios::badbit); //set the state
return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
e buffer; //get buffer
in >> buffer; //read data
if (buffer != cliteral) //if it failed
in.setstate(in.rdstate() | std::ios::badbit); //set the state
return in;
}
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
return std::operator>>(in, carray);
}
template<class e, class t, class a>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, a& obj) {
return in >> obj; //read data
}
template<class T>
std::istream& custom_complex(std::istream& file, std::complex<T>& obj) {
if (!file)
return file;
std::string fullline;
std::getline(file, fullline);
T r, i;
std::stringstream ss(std::move(fullline));
if (ss >> '(' >> r >> ',' >> 'i' >> ')') {
obj = std::complex<T>(r, i);
return file;
}
ss.clear();
ss.seekg(0);
if (ss >> '(' >> r >> 'i' >> ')') {
obj = std::complex<T>(r, i);
return file;
}
ss.clear();
ss.seekg(0);
if (ss >> r >> ',' >> i) {
obj = std::complex<T>(r, i);
return file;
}
ss.clear();
ss.seekg(0);
if (ss >> r >> i) {
obj = std::complex<T>(r, i);
return file;
}
file.setstate(file.rdstate() | std::ios::badbit);
return file;
}
struct first {
std::string name;
double something;
};
struct second {
int myint;
std::complex<double> mycomplex;
};
struct mega {
std::vector<first> list1;
std::vector<second> list2;
};
std::istream& operator>>(std::istream& file, first& obj) {
std::string symbol;
char equals;
while(file >> symbol) {
if (symbol[0] == '#') {
std::getline(file, symbol);
} else if (symbol == "<FIRST_END>") {
break;
} else if (symbol == "NAME") {
if (! (file>>'='>>obj.name) )
std::cerr << symbol << " incorrectly formatted";
} else if (symbol == "SOMETHING") {
if (! (file>>'='>>obj.something) )
std::cerr << symbol << " incorrectly formatted";
} else { //not a member: failure
std::cerr << symbol << " is not a member of first";
file.setstate(file.rdstate() | std::ios::badbit);
break;
}
}
return file;
}
std::istream& operator>>(std::istream& file, second& obj) {
std::string symbol;
char equals;
while(file >> symbol) {
if (symbol[0] == '#') {
std::getline(file, symbol);
} else if (symbol == "<SECOND_END>") {
break;
} else if (symbol == "INT") {
if (! (file>>'='>>obj.myint) )
std::cerr << symbol << " incorrectly formatted";
} else if (symbol == "COMPLEX") {
if (! (file>>'=' && custom_complex(file,obj.mycomplex)) )
std::cerr << symbol << " incorrectly formatted";
} else { //not a member: failure
std::cerr << symbol << " is not a member of second";
file.setstate(file.rdstate() | std::ios::badbit);
break;
}
}
return file;
}
std::istream& operator>>(std::istream& file, mega& obj) {
std::string symbol;
while(file >> symbol) {
if (symbol[0] == '#') {
std::getline(file, symbol);
} else if (symbol == "<FIRST_BEGIN>") {
first t;
if (file >> t)
obj.list1.push_back(t);
} else if (symbol == "<SECOND_BEGIN>") {
second t;
if (file >> t)
obj.list2.push_back(t);
} else {
std::cerr << symbol << " is not a member of mega";
file.setstate(file.rdstate() | std::ios::badbit);
}
}
return file;
}
int main() {
mega obj;
std::cin >> obj;
std::cout << obj.list2.size(); //1 if success
}