fork download
  1. #include <cstring>
  2. #include <cstdlib>
  3. #include <cassert>
  4. #include <cstdint>
  5.  
  6. #include <iostream>
  7. #include <sstream>
  8. #include <algorithm>
  9. #include <vector>
  10. #include <iterator>
  11. #include <string>
  12.  
  13. template <typename T>
  14. class TrivialAllocator {
  15. size_t default_allocate;
  16. size_t allocated;
  17.  
  18. size_t const size;
  19. T * elements;
  20.  
  21. public:
  22. TrivialAllocator( size_t size, size_t default_allocate = 1 )
  23. : default_allocate( default_allocate ),
  24. allocated( 0 ), size( size ),
  25. elements( (T*)malloc(sizeof(T)*size) )
  26. { }
  27.  
  28. ~TrivialAllocator() { free( elements ); }
  29.  
  30. T * allocate( size_t count ) {
  31. assert( allocated + count < size );
  32. T * ret = elements + allocated;
  33. allocated += count;
  34. return ret;
  35. }
  36.  
  37. T * allocate() {
  38. return allocate( default_allocate );
  39. }
  40. };
  41.  
  42. struct BasicStudentInfo {
  43. char * name;
  44. char * id;
  45.  
  46. BasicStudentInfo( char const * name,
  47. char const * id,
  48. TrivialAllocator<char> & alloc )
  49. : name( alloc.allocate(strlen(name)+1) ),
  50. id( alloc.allocate(strlen(id)+1) )
  51. {
  52. strcpy( this->name, name );
  53. strcpy( this->id, id );
  54. }
  55.  
  56. virtual void print( std::ostream & output ) {
  57. output << "name : " << name << ", id : " << id;
  58. }
  59. };
  60.  
  61. struct AdvanceStudentInfo : BasicStudentInfo {
  62. char * sex;
  63. char * school;
  64.  
  65. AdvanceStudentInfo( char const * name,
  66. char const * id,
  67. char const * sex,
  68. char const * school,
  69. TrivialAllocator<char> & alloc )
  70. : BasicStudentInfo( name, id, alloc ),
  71. sex( alloc.allocate(strlen(sex)+1) ),
  72. school( alloc.allocate(strlen(school)+1) )
  73. {
  74. strcpy( this->sex, sex );
  75. strcpy( this->school, school );
  76. }
  77.  
  78. virtual void print( std::ostream & output ) {
  79. output << "name : " << name << ", id : " << id
  80. << ", sex : " << sex << ", school : " << school;
  81. }
  82. };
  83.  
  84. template <typename Score>
  85. struct ScoreEntry {
  86. BasicStudentInfo * info;
  87. Score * scores;
  88.  
  89. ScoreEntry( BasicStudentInfo * info, Score * scores )
  90. : info( info ), scores( scores )
  91. { }
  92. };
  93.  
  94. template <typename Score>
  95. class Transcript {
  96.  
  97. TrivialAllocator<char> char_alloc;
  98. TrivialAllocator<Score> score_alloc;
  99. TrivialAllocator<AdvanceStudentInfo> info_alloc;
  100.  
  101. std::vector< ScoreEntry<Score>> entries;
  102. size_t score_count;
  103.  
  104. public:
  105. Transcript( size_t score_count )
  106. : char_alloc( 100 ),
  107. score_alloc( 100, score_count ),
  108. info_alloc( 100 ),
  109. score_count( score_count )
  110. { }
  111.  
  112. void read( std::istream & input ) {
  113. using namespace std;
  114. string name, id;
  115. while( input ) {
  116. if( !(input >> name >> id) ) break;
  117. BasicStudentInfo * info = info_alloc.allocate();
  118. new (info) BasicStudentInfo( name.c_str(), id.c_str(), char_alloc );
  119.  
  120. Score * scores = score_alloc.allocate();
  121. for( size_t i = 0; i != score_count; ++i )
  122. input >> scores[ i ];
  123.  
  124. entries.push_back( ScoreEntry<Score>(info, scores) );
  125. }
  126. }
  127.  
  128. void print( std::ostream & output ) {
  129. for( auto entry = entries.begin(); entry != entries.end(); ++entry ) {
  130. entry->info->print( output );
  131.  
  132. output << ", scores : ";
  133. std::copy( entry->scores, entry->scores + score_count,
  134. std::ostream_iterator<Score>(output, " ") );
  135. output << std::endl;
  136. }
  137. }
  138. };
  139.  
  140. int main() {
  141.  
  142. using namespace std;
  143.  
  144. Transcript<int> transcript( 3 );
  145.  
  146. istringstream input( "Alice A01 99 85 90\nAdam A02 77 80 91\n" );
  147. transcript.read( input );
  148. transcript.print( cout );
  149.  
  150. }
  151.  
Success #stdin #stdout 0s 3068KB
stdin
Standard input is empty
stdout
name : Alice, id : A01, scores : 99 85 90 
name : Adam, id : A02, scores : 77 80 91