#include <cstring>
#include <cstdlib>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <string>
template <typename T>
class TrivialAllocator {
size_t default_allocate;
size_t allocated;
size_t const size;
T * elements;
public:
TrivialAllocator( size_t size, size_t default_allocate = 1 )
: default_allocate( default_allocate ),
allocated( 0 ), size( size ),
elements( (T*)malloc(sizeof(T)*size) )
{ }
~TrivialAllocator() { free( elements ); }
T * allocate( size_t count ) {
assert( allocated + count < size );
T * ret = elements + allocated;
allocated += count;
return ret;
}
T * allocate() {
return allocate( default_allocate );
}
};
struct BasicStudentInfo {
char * name;
char * id;
BasicStudentInfo( char const * name,
char const * id,
TrivialAllocator<char> & alloc )
: name( alloc.allocate(strlen(name)+1) ),
id( alloc.allocate(strlen(id)+1) )
{
strcpy( this->name, name );
strcpy( this->id, id );
}
virtual void print( std::ostream & output ) {
output << "name : " << name << ", id : " << id;
}
};
struct AdvanceStudentInfo : BasicStudentInfo {
char * sex;
char * school;
AdvanceStudentInfo( char const * name,
char const * id,
char const * sex,
char const * school,
TrivialAllocator<char> & alloc )
: BasicStudentInfo( name, id, alloc ),
sex( alloc.allocate(strlen(sex)+1) ),
school( alloc.allocate(strlen(school)+1) )
{
strcpy( this->sex, sex );
strcpy( this->school, school );
}
virtual void print( std::ostream & output ) {
output << "name : " << name << ", id : " << id
<< ", sex : " << sex << ", school : " << school;
}
};
template <typename Score>
struct ScoreEntry {
BasicStudentInfo * info;
Score * scores;
ScoreEntry( BasicStudentInfo * info, Score * scores )
: info( info ), scores( scores )
{ }
};
template <typename Score>
class Transcript {
TrivialAllocator<char> char_alloc;
TrivialAllocator<Score> score_alloc;
TrivialAllocator<AdvanceStudentInfo> info_alloc;
std::vector< ScoreEntry<Score>> entries;
size_t score_count;
public:
Transcript( size_t score_count )
: char_alloc( 100 ),
score_alloc( 100, score_count ),
info_alloc( 100 ),
score_count( score_count )
{ }
void read( std::istream & input ) {
using namespace std;
string name, id;
while( input ) {
if( !(input >> name >> id) ) break;
BasicStudentInfo * info = info_alloc.allocate();
new (info) BasicStudentInfo( name.c_str(), id.c_str(), char_alloc );
Score * scores = score_alloc.allocate();
for( size_t i = 0; i != score_count; ++i )
input >> scores[ i ];
entries.push_back( ScoreEntry<Score>(info, scores) );
}
}
void print( std::ostream & output ) {
for( auto entry = entries.begin(); entry != entries.end(); ++entry ) {
entry->info->print( output );
output << ", scores : ";
std::copy( entry->scores, entry->scores + score_count,
std::ostream_iterator<Score>(output, " ") );
output << std::endl;
}
}
};
int main() {
using namespace std;
Transcript<int> transcript( 3 );
istringstream input( "Alice A01 99 85 90\nAdam A02 77 80 91\n" );
transcript.read( input );
transcript.print( cout );
}