bool erase_test( ) { bool rc = true; std::string s1( "Hello, World!" ); s1.erase( ); if( s1 != "" || s1.size( ) != 0 || INSANE( s1 ) ) FAIL std::string s2( "Hello, World!" ); s2.erase( 2, 3 ); if( s2 != "He, World!" || s2.size( ) != 10 || INSANE( s2 ) ) FAIL std::string s3( "Hello, World!" ); s3.erase( 7, 6 ); if( s3 != "Hello, " || s3.size( ) != 7 || INSANE( s3 ) ) FAIL std::string s4( "Hello, World!" ); s4.erase( s4.begin( ) ); if( s4 != "ello, World!" || s4.size( ) != 12 || INSANE( s4 ) ) FAIL std::string s5( "Hello, World!" ); s5.erase( s5.begin( ) + 2, s5.begin( ) + 5 ); if( s5 != "He, World!" || s5.size( ) != 10 || INSANE( s5 ) ) FAIL return( rc ); }
bool iterator_replace_test( ) { bool rc = true; const std::string s1( "Insert me!" ); std::string t1( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t1.replace( t1.begin( ), t1.end( ), s1 ); if( t1 != "Insert me!" || INSANE( t1 ) ) FAIL std::string t2( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t2.replace( t2.begin( ), t2.begin( ) + 1, s1 ); if( t2 != "Insert me!BCDEFGHIJKLMNOPQRSTUVWXYZ" || INSANE( t2 ) ) FAIL std::string t3( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t3.replace( t3.end( ), t3.end( ), s1 ); if( t3 != "ABCDEFGHIJKLMNOPQRSTUVWXYZInsert me!" || INSANE( t3 ) ) FAIL std::string t4( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t4.replace( t4.begin( ) + 4, t4.begin( ) + 7, s1 ); if( t4 != "ABCDInsert me!HIJKLMNOPQRSTUVWXYZ" || INSANE( t4 ) ) FAIL std::string t5( "Shorty" ); t5.replace( t5.begin( ), t5.begin( ) + 2, 2, 'x' ); if( t5 != "xxorty" || INSANE( t5 ) ) FAIL // Need to test other iterator replace methods. return( rc ); }
bool construct_test( ) { int i; typedef std::set< int > seti_t; seti_t s1; std::set< char > s2; // to do: construct with different alloc/comp std::set< char* > s3; seti_t *s4 = new seti_t(); if( INSANE(s1) || s1.size() || !s1.empty() ) FAIL if( INSANE(s2) || s2.size() || !s2.empty() ) FAIL if( INSANE(s3) || s3.size() || !s3.empty() ) FAIL if( INSANE(*s4) || s4->size() || !s4->empty() ) FAIL delete s4; // test template constructor, note: no default args yet int init[] = { 1, 2, 3, 4 }; int initsize = sizeof(init)/sizeof(int); seti_t s5( init, init + initsize, seti_t::key_compare(), seti_t::allocator_type() ); if( INSANE(s5) || s5.size() != initsize ) FAIL for( i = 0; i < s5.size(); i++ ) { if( s5.find( init[i] ) == s5.end() ) FAIL } return( true ); }
/* ------------------------------------------------------------------ * iterator_test( ) * Test the iterator functionality */ bool iterator_test( ) { typedef std::multiset< int > s_t; s_t s1; s_t::iterator it; s_t::const_iterator cit; //use nums[] so numbers are not inserted in simple order int nums[] = { 2,1,5,6,7,8,4,9,3,0 }; for( int i = 0; i < 10; i++ ){ for( int j = 0; j < 5; j++ ){ s1.insert( nums[i] ); } } //test increment and dereferencing ( will be sorted by std::less<int> ) it = s1.begin( ); int ans = *it; for( int i = 0; i < 10 ; i++ ){ for( int j = 0; j < 5; j++ ){ if( INSANE( s1 ) || ans != i || *it != i ) FAIL if( i%2 ) ans = *(it++) + ( (j == 4) ? 1 : 0 ); else ans = *(++it); } } //and again with const iterator cit = s1.begin( ); ans = *cit; for( int i = 0; i < 10 ; i++ ){ for( int j = 0; j < 5; j++ ){ if( INSANE( s1 ) || ans != i || *cit != i ) FAIL if( i%2 ) ans = *(cit++) + ( (j == 4) ? 1 : 0 ); else ans = *(++cit); } } //test decrement ( will be sorted by std::less<int> ) it = s1.end( ); for( int i = 9; i > 0 ; i-- ){ for( int j = 0; j < 5; j++ ){ if( i%2 ) ans = *(--it); else ans = *(it--) - ( (j == 0) ? 1 : 0 ); if( INSANE( s1 ) || ans != i || *it != i ) FAIL } } //and again with const iterator cit = s1.end( ); for( int i = 9; i > 0 ; i-- ){ for( int j = 0; j < 5; j++ ){ if( i%2 ) ans = *(--cit); else ans = *(cit--) - ( (j == 0) ? 1 : 0 ); if( INSANE( s1 ) || ans != i || *cit != i ) FAIL } } return( true ); }
void CityTreeQueue::Remove (CityTree *t) { CityTree *p=NULL; Assert(m_head); if (m_head == t) { m_head = m_head->m_next; if (m_head == NULL) { m_tail = NULL; } t->m_next=NULL; m_count--; return; } else { for (p=m_head; p; p = p->m_next) { if (p->m_next == t) { p->m_next = t->m_next; if (p->m_next == NULL) { m_tail = p; } t->m_next = NULL; m_count--; return; } } } INSANE(COULD_NOT_REMOVE_TREE); }
double GoalSettle::Compute_Raw_Priority(AiMain *ai) { #ifdef _DEBUG MapPointData *size; size = ai->m_map->GetSize(); Assert(m_pos); Assert(m_XYpos); Assert(0 <= m_XYpos->x); Assert(m_XYpos->x < size->x*2); Assert(0 <= m_XYpos->y); Assert(m_XYpos->y < size->y); Assert(0 <= m_XYpos->z); Assert(m_XYpos->z < size->z); Assert(0 <= m_pos->x); Assert(m_pos->x < size->x); Assert(0 <= m_pos->y); Assert(m_pos->y < size->y); Assert(0 <= m_pos->z); Assert(m_pos->z < size->z); #endif if (ai->m_my_player_id == PLAYER_INDEX_VANDALS) return BAD_UTILITY; double env_bonus; switch (m_environment) { case SETTLE_ENVIRONMENT_LAND: env_bonus = 0.0; break; case SETTLE_ENVIRONMENT_SPACE: env_bonus = fz_settle_bonus_space; break; case SETTLE_ENVIRONMENT_WATER: env_bonus = fz_settle_bonus_water; break; case SETTLE_ENVIRONMENT_ISLAND: env_bonus = fz_settle_bonus_island; break ; default: INSANE(SETTLE_ENVIRONMENT_UNKNOWN); } int distance_to_us = ai->m_planner->the_strategic_map->Get_Distance_To_Our_Empire(*m_XYpos); raw_priority = ai->m_planner->the_AIP.settle_priority; raw_priority += ArmyGoal::Compute_Raw_Priority(ai, -1, -1, 0, 1, 0, 1, 1); raw_priority += m_value * fz_settle_value_coef; raw_priority += env_bonus; return raw_priority; }
void Squad::Load(CivArchive &archive) { int i; Agent * the_agent= NULL; sint32 num_agents; AGENT_TYPE real_type; BSetID id; m_squad_strength.Serialize(archive); num_agents = archive.GetSINT32() ; for (i = 0; i < num_agents; i++) { id = archive.GetUINT32(); real_type = AGENT_TYPE(archive.GetSINT32()); switch (real_type) { case AGENT_TYPE_ARMY: the_agent = the_team->ai->m_army_set->Find(id); break; case AGENT_TYPE_CITY: the_agent = the_team->ai->m_city_set->Find(id); break; default: INSANE(SQUAD_LOAD_UNKNOWN_AGENT); break; } Assert(the_agent); Add_Agent(ai, the_agent); } my_goal_id = archive.GetSINT32(); my_strategic_goal = NULL; already_committed = FALSE; }
bool insert_test( ) { bool rc = true; std::string s0( "INSERTED" ); std::string s1( "Hello, World!" ); s1.insert( 2, s0 ); if( s1 != "HeINSERTEDllo, World!" || s1.size( ) != 21 || INSANE( s1 ) ) { FAIL } std::string s2( "Hello, World!" ); s2.insert( 0, s0 ); if( s2 != "INSERTEDHello, World!" || s2.size( ) != 21 || INSANE( s2 ) ) { FAIL } std::string s3( "Hello, World!" ); s3.insert( 13, s0 ); if( s3 != "Hello, World!INSERTED" || s3.size( ) != 21 || INSANE( s3 ) ) { FAIL } std::string s4( "Hello, World!" ); s4.insert( 0, s0, 2, 2 ); if( s4 != "SEHello, World!" || s4.size( ) != 15 || INSANE( s4 ) ) { FAIL } std::string s5( "Hello, World!" ); s5.insert( 0, s0, 2, 128 ); if( s5 != "SERTEDHello, World!" || s5.size( ) != 19 || INSANE( s5 ) ) { FAIL } // Do multiple insertions to verify reallocations. // This should probably also be done for the other insert methods as well. std::string s6( "Hello" ); char input = 'a'; for( int i = 0; i < 10; ++i ) { std::string::iterator p = s6.insert( s6.begin( ), input ); if( *p != input ) FAIL; if( s6.size( ) != 6 + i ) FAIL; if( INSANE( s6 ) ) FAIL; ++input; } if( s6 != "jihgfedcbaHello" ) FAIL; std::string s7( "Hello, World!" ); s7.insert( s7.end( ), 3, 'z' ); if( s7 != "Hello, World!zzz" || s7.size( ) != 16 || INSANE( s7 ) ) { FAIL } // Need to test other insert methods. return( rc ); }
bool replace_test( ) { bool rc = true; const std::string s1( "Insert me!" ); std::string t1( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t1.replace( 0, std::string::npos, s1, 0, std::string::npos ); if( t1 != "Insert me!" || INSANE( t1 ) ) FAIL std::string t2( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t2.replace( 0, 1, s1, 0, std::string::npos ); if( t2 != "Insert me!BCDEFGHIJKLMNOPQRSTUVWXYZ" || INSANE( t2 ) ) FAIL std::string t3( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t3.replace( 1, 0, s1, 0, 1 ); if( t3 != "AIBCDEFGHIJKLMNOPQRSTUVWXYZ" || INSANE( t3 ) ) FAIL std::string t4( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t4.replace( 26, 0, s1, 0, std::string::npos ); if( t4 != "ABCDEFGHIJKLMNOPQRSTUVWXYZInsert me!" || INSANE( t4 ) ) FAIL std::string t5( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); t5.replace( 4, 3, s1, 2, 5 ); if( t5 != "ABCDsert HIJKLMNOPQRSTUVWXYZ" || INSANE( t5 ) ) FAIL std::string t6( "Shorty" ); t6.replace( 1, 2, s1, 0, 2 ); if( t6 != "SInrty" || INSANE( t6 ) ) FAIL // Need to test other replace methods. return( rc ); }
/* ------------------------------------------------------------------ * hint_ins_test( ) * insert with hints */ bool hint_ins_test( ) { typedef std::multiset< int > msii_t; typedef msii_t::iterator msiter_t; msii_t s1; msiter_t it; //hint insert tests s1.clear(); s1.insert( s1.end(), 4 ); s1.insert( s1.end(), 7 ); s1.insert( --s1.end(), 6 ); s1.insert( s1.end(), 8 ); s1.insert( s1.begin(), 2 ); s1.insert( ++s1.begin(), 3 ); s1.insert( s1.find(6), 5 ); s1.insert( s1.end(), 0 ); //invalid hint s1.insert( s1.find(0), 1 ); //invalid hint s1.insert( ++s1.begin(), 9 ); //invalid hint for( int i = 0; i < 10; i++){ it = s1.find( i ); if( INSANE( s1 ) || s1.size() != 10 || s1.empty() || it == s1.end() || *it != i ) FAIL } s1.clear(); msiter_t it2; s1.insert( s1.end(), 0 ); s1.insert( s1.end(), 0 ); it = s1.insert( s1.end(), 1 ); it2 = s1.insert( s1.find(1), 1 ); s1.insert( s1.end(), 1 ); s1.insert( s1.end(), 2 ); s1.insert( it2, 0 ); s1.insert( --s1.end(), 2 ); s1.insert( ++(++it), 2 ); it = s1.insert( s1.begin(), 4 ); //invalid hint, insert closest s1.insert( s1.find(1), 4 ); //invalid hint, insert closest s1.insert( it2, 4 ); //invalid hint, insert closest s1.insert( ++s1.find(4), 3 ); //invalid hint, insert closest s1.insert( it, 3 ); //invalid hint, insert closest s1.insert( ++s1.find(4), 3 ); //invalid hint, insert closest it = s1.begin(); for( int i = 0; i < 5; i++){ for( int j = 0; j < 3; j++){ if( INSANE( s1 ) || s1.size() != 15 || s1.empty() || it == s1.end() || *it != i ) FAIL ++it; } } return( true ); }
/* ------------------------------------------------------------------ * copy_test( ) * Test all things plagiarised */ bool copy_test( ) { typedef std::multiset< int > s_t; s_t s1; int i, j; for( i = 0; i < 10; i++ ){ for( j = 0; j < 10; j++ ){ s1.insert( i ); } } s_t s1cpy( s1 ); if( INSANE( s1cpy ) || s1cpy.size() != 100 ) FAIL //check it copied to new one ok for( i = 0; i < 10; i++ ){ s_t::iterator it = s1cpy.find( i ); for( j = 0; j < 10; j++, ++it ){ if( *it != i ) FAIL } } s1cpy.erase( 1 ); if( INSANE( s1cpy ) || s1cpy.size() != 90 ) FAIL //check it is a copy and old not effecting new one if( INSANE( s1 ) || s1.size() != 100 ) FAIL for( i = 0; i < 10; i++ ){ s_t::iterator it = s1.find( i ); for( j = 0; j < 10; j++, ++it ){ if( *it != i ) FAIL } } //assignment style construct s_t s1cpy2 = s1; if( INSANE( s1cpy2 ) || s1cpy2.size() != 100 ) FAIL for( i = 0; i < 10; i++ ){ s_t::iterator it = s1cpy2.find( i ); for( j = 0; j < 10; j++, ++it ){ if( *it != i ) FAIL } } //check assignment s1cpy.clear(); s1.erase( 5 ); s1.insert( 11 ); s1 = s1cpy = s1cpy2; if( INSANE( s1cpy ) || s1cpy.size() != 100 ) FAIL if( INSANE( s1 ) || s1.size() != 100 ) FAIL for( i = 0; i < 10; i++ ){ s_t::iterator it = s1.find( i ); s_t::iterator it2 = s1cpy.find( i ); for( j = 0; j < 10; j++, ++it ){ if( *it != i ) FAIL if( *it != i ) FAIL } } return( true ); }
BOOL CityAgent::PutCitizenBestTile( AiMain *ai, const sint32 idx_citizen, TileUtility *open_tile[k_NUM_CITY_TILES], sint32 &idx_tile) { BOOL searching=TRUE; BOOL is_unknown_id=FALSE; BOOL r; sint32 tmp; Assert(0 <= idx_tile); Assert(idx_tile < k_NUM_CITY_TILES); #ifdef _DEBUG sint32 finite_loop=0; #endif do { if (open_tile[idx_tile]) { START_MULTI_CLOCK r = ai->m_population->TryPlacePop(m_id.GetVal(), idx_citizen, ai->my_player_index, &open_tile[idx_tile]->m_pos, &is_unknown_id); END_MULTI_CLOCK if (r) { ai->m_world->GetProd(&(open_tile[idx_tile]->m_pos), &tmp); m_total_field_prod += tmp; ai->m_world->GetFood(&(open_tile[idx_tile]->m_pos), &tmp); m_total_field_food += tmp; m_num_field_workers++; open_tile[idx_tile] = NULL; searching = FALSE; } else { INSANE(COULD_NOT_PLACE_POP); } } idx_tile++; Assert(++finite_loop < 100000); } while (searching && (idx_tile < k_NUM_CITY_TILES)); return !searching; }
bool construct_test( ) { bool rc = true; std::string s1; std::string s2( "Hello, World" ); std::string s3( "Hello, World", 3 ); std::string s4( s2 ); std::string s5( s2, 7, 2 ); std::string s6( s2, 7, 1024 ); std::string s7( s2, 1 ); std::string s8( 16, 'x' ); if( s1.size( ) != 0 || s1 != "" || INSANE( s1 ) ) FAIL if( s2.size( ) != 12 || s2 != "Hello, World" || INSANE( s2 ) ) FAIL if( s3.size( ) != 3 || s3 != "Hel" || INSANE( s3 ) ) FAIL if( s4.size( ) != 12 || s4 != "Hello, World" || INSANE( s4 ) ) FAIL if( s5.size( ) != 2 || s5 != "Wo" || INSANE( s5 ) ) FAIL if( s6.size( ) != 5 || s6 != "World" || INSANE( s6 ) ) FAIL if( s7.size( ) != 11 || s7 != "ello, World" || INSANE( s7 ) ) FAIL if( s8.size( ) != 16 || s8 != "xxxxxxxxxxxxxxxx" || INSANE( s8 ) ) FAIL return( rc ); }
BOOL GoalBombard::WithinRange ( AiMain *ai, Agent *agent, const SUB_TASK_TYPE & sub_task ) { ArmyAgent *army_agent; switch (agent->GetType()) { case AGENT_TYPE_ARMY: BOOL close_enough; army_agent = (ArmyAgent *) agent; if (army_agent->GetRemainingPathPoints(ai) <= 1) return true; if (sub_task == SUB_TASK_CARGO_TO_BOARD || sub_task == SUB_TASK_TRANSPORT_TO_BOARD) return army_agent->AtEndOfPath(ai); close_enough = army_agent->CanBombardTarget(ai, *m_pos); return close_enough; break; case AGENT_TYPE_CITY: break; case AGENT_TYPE_UNKNOWN: default: INSANE(DISTANCE_TO_SQUAD_GOAL_UNKNOWN); break; } return false; }
void Squad::DumpGoal(AiMain *ai, const GOAL_TYPE goal_type, const double matching_value) { char text[255]; switch (goal_type) { case GOAL_TYPE_NULL: sprintf (text, "bad!?!?"); break; case GOAL_TYPE_DEFENSE: sprintf (text, "defense"); break; case GOAL_TYPE_ATTACK: sprintf (text, "attack"); break; case GOAL_TYPE_SETTLE: sprintf (text, "settle"); break; case GOAL_TYPE_EXPLORE: sprintf (text, "explore"); break; case GOAL_TYPE_CONSTRUCT_BUILDING: sprintf (text, "BLG"); break; case GOAL_TYPE_CONSTRUCT_FREIGHT: sprintf (text, "FREIGHT"); break; case GOAL_TYPE_CONSTRUCT_WONDER: sprintf (text, "WONDER"); break; case GOAL_TYPE_TRANSPORT: sprintf (text, "transport"); break; case GOAL_TYPE_ENSLAVE: sprintf (text, "enslave"); break; case GOAL_TYPE_BOMBARD: sprintf (text, "bombard"); break; case GOAL_TYPE_BUILD_SUPPLEMENTAL: sprintf (text, "Bsup"); break; case GOAL_TYPE_BUILD_LIST: sprintf (text, "Blist"); break; case GOAL_TYPE_PERIMETER: sprintf (text, "perimeter"); break; case GOAL_TYPE_CHOKEPOINT: sprintf (text, "chokepoint"); break; case GOAL_TYPE_PATROL: sprintf (text, "patrol"); break; case GOAL_TYPE_RUSTLE: sprintf (text, "rustle"); break; case GOAL_TYPE_EXPEL: sprintf (text, "expel"); break; case GOAL_TYPE_SALLY: sprintf (text, "sally"); break; case GOAL_TYPE_ATTACK_REGION: sprintf (text, "Attack Region"); break; case GOAL_TYPE_SEIGE: case GOAL_TYPE_CONVERT_CITY: case GOAL_TYPE_BIOTERROR_CITY: case GOAL_TYPE_NANOATTACK_CITY: case GOAL_TYPE_HARASS_CITY: case GOAL_TYPE_PILLAGE: case GOAL_TYPE_PIRATE: case GOAL_TYPE_COUNTER_STEALTH: case GOAL_TYPE_BONUS_FOOD: case GOAL_TYPE_GOODY_HUT: case GOAL_TYPE_PLANT_NUKE: case GOAL_TYPE_MAKE_PARK: case GOAL_TYPE_CAUSE_UNHAPPINESS: case GOAL_TYPE_ESTABLISH_EMBASSY: case GOAL_TYPE_FRANCHISING: case GOAL_TYPE_STEAL_TECHNOLOGY: case GOAL_TYPE_INCITE_REVOLUTION: case GOAL_TYPE_INJOIN: case GOAL_TYPE_ASSASINATE_RULER: case GOAL_TYPE_UNDERGROUND_RAILWAY: case GOAL_TYPE_NUKE_CITY: case GOAL_TYPE_WANDER: case GOAL_TYPE_REFORM_CITY: case GOAL_TYPE_SUE_FRANCHISE: case GOAL_TYPE_PROBE_WORMHOLE: case GOAL_TYPE_RECOVER_PROBE: my_strategic_goal->GetDebugName(text); break; case GOAL_TYPE_RETREAT: sprintf (text, "retreat"); break; default: INSANE(UNKNOWN_GOAL_TYPE); sprintf (text, "*unknown*"); break; } char valstr[100]; sprintf (valstr, " %3.1f S: %d", matching_value, squad_ID); strcat (text, valstr); sint32 i; Agent *the_agent; for (i=0; i<my_agents.count; i++){ the_agent = (Agent *) my_agents.Return_Data_By_Number( i ); the_agent->DumpStr(ai, text); } }
bool append_test( ) { bool rc = true; // The sizes of the test strings used here are intended to explore // both appending without reallocation and appending with re- // allocation. A string can not be reused between tests because // an enlarged capacity is never reduced. std::string s1( "123456" ); std::string s2( "x" ); s1 += s2; if( s1 != "123456x" || s1.size( ) != 7 || INSANE( s1 ) ) FAIL s1 += s2; if( s1 != "123456xx" || s1.size( ) != 8 || INSANE( s1 ) ) FAIL std::string s3( "123456" ); s3 += "x"; if( s3 != "123456x" || s3.size( ) != 7 || INSANE( s3 ) ) FAIL s3 += "y"; if( s3 != "123456xy" || s3.size( ) != 8 || INSANE( s3 ) ) FAIL std::string s4( "123456" ); s4 += 'x'; if( s4 != "123456x" || s4.size( ) != 7 || INSANE( s4 ) ) FAIL s4 += 'z'; if( s4 != "123456xz" || s4.size( ) != 8 || INSANE( s4 ) ) FAIL std::string s5( "123456" ); std::string s6( "Hello, World!" ); s5.append( s6, 12, 1 ); if( s5 != "123456!" || s5.size( ) != 7 || INSANE( s5 ) ) FAIL s5.append( s6, 0, 3 ); if( s5 != "123456!Hel" || s5.size( ) != 10 || INSANE( s5 ) ) FAIL std::string s7( "123456" ); s7.append( "fizzle", 1 ); if( s7 != "123456f" || s7.size( ) != 7 || INSANE( s7 ) ) FAIL s7.append( "fizzle", 3 ); if( s7 != "123456ffiz" || s7.size( ) != 10 || INSANE( s7 ) ) FAIL std::string s8( "123456" ); s8.append( "x" ); if( s8 != "123456x" || s8.size( ) != 7 || INSANE( s8 ) ) FAIL s8.append( "abc" ); if( s8 != "123456xabc" || s8.size( ) != 10 || INSANE( s8 ) ) FAIL std::string s9( "123456" ); s9.append( 1, 'x' ); if( s9 != "123456x" || s9.size( ) != 7 || INSANE( s9 ) ) FAIL s9.append( 3, 'y' ); if( s9 != "123456xyyy" || s9.size( ) != 10 || INSANE( s9 ) ) FAIL std::string s10( "123456" ); s10.push_back( 'z' ); if( s10 != "123456z" || s10.size( ) != 7 || INSANE( s10 ) ) FAIL s10.push_back( 'a' ); if( s10 != "123456za" || s10.size( ) != 8 || INSANE( s10 ) ) FAIL return( rc ); }
/* ------------------------------------------------------------------ * access_test( ) * insert, find, erase, count */ bool access_test( ) { typedef std::multiset< int > msii_t; typedef msii_t::iterator msiter_t; msii_t s1; int num[] = {11,11,11,10,4,8,8,2,1,12,13,19,7,18,4,2,2,17,11}; int notnum[] = {3,5,6,9,14,15,16}; int const num_size = sizeof(num) / sizeof(int); int const notnum_size = sizeof(notnum) / sizeof(int); //insert for( int i = 0; i < num_size; i++ ){ msiter_t it; it = s1.insert( num[i] ); if( INSANE( s1 ) || s1.size() != (i+1) || s1.empty() || it == s1.end() || *it != num[i] ) FAIL } //find inserted for( int i = 0; i < num_size; i++ ){ msiter_t it = s1.find( num[i] ); if( INSANE( s1 ) || s1.size() != num_size || s1.empty() || it == s1.end() || *it != num[i] ) FAIL } //find not inserted for( int i = 0; i < notnum_size; i++ ){ msiter_t it = s1.find( notnum[i] ); if( INSANE( s1 ) || s1.size() != num_size || s1.empty() || it != s1.end() ) FAIL } //insert again for( int i = 0; i < num_size; i++ ){ msiter_t it; it = s1.insert( num[i] ); if( INSANE( s1 ) || s1.size() != (num_size+i+1) || s1.empty() || it == s1.end() || *it != num[i] ) FAIL } //spot checks on contents if( s1.count( 11 ) != 8 ) FAIL //count the number of 11's msiter_t it = s1.find( 11 ); for( int i = 0; i < 4; i++ ){ if( INSANE( s1 ) || s1.size() != num_size*2 || s1.empty() || it == s1.end() || *it != 11 ) FAIL ++it; } //erase tests //erase first of multiple keys s1.erase( s1.find( 11 ) ); if( INSANE( s1 ) || s1.size() != num_size*2-1 || s1.count( 11 ) != 7 ) FAIL //erase last of multiple keys s1.erase( --( s1.find( 12 ) ) ); if( INSANE( s1 ) || s1.size() != num_size*2-2 || s1.count( 11 ) != 6 ) FAIL //erase middle of multiple keys s1.erase( --(--(--( s1.find( 12 ) ))) ); if( INSANE( s1 ) || s1.size() != num_size*2-3 || s1.count( 11 ) != 5 ) FAIL //erase all keys s1.erase( s1.find(12) ); s1.erase( s1.find(12) ); if( INSANE( s1 ) || s1.size() != num_size*2-5 || s1.count( 12 ) != 0 ) FAIL //erase all keys other method if( s1.erase( 2 ) != 6 ) FAIL; if( INSANE( s1 ) || s1.size() != num_size*2-11 || s1.count( 2 ) != 0 ) FAIL return( true ); }
/* ------------------------------------------------------------------ * allocator_test * test stateful allocators and exception handling */ bool allocator_test( ) { typedef std::multiset< int, std::less<int>, LowMemAllocator<int> > set_t; LowMemAllocator<int> mem(200); mem.SetTripOnAlloc(); set_t s( set_t::key_compare(), mem ); bool thrown = false; //LowMemAllocator is set to trip after 200 allocations or 100 inserts //(each unique key gets 2 allocations in multimap/set) try{ for( int i=0; i<101; i++ ){ s.insert( i ); } }catch( std::bad_alloc const & ){ mem = s.get_allocator(); if( mem.GetNumAllocs() != 201 ) FAIL //should have failed on 201st if( INSANE(s) || s.size() != 100 ) FAIL thrown = true; } if( !thrown ) FAIL //exception should have been thrown s.clear(); mem.Reset(200); mem.SetTripOnConstruct(); thrown = false; //LowMemAllocator is set to trip after 100 allocations try{ for( int i=0; i<101; i++ ){ s.insert( i ); } }catch( std::bad_alloc const & ){ mem = s.get_allocator(); if( mem.GetNumConstructs() != 201 ) FAIL //should have cleaned up last extra alloc if( mem.GetNumAllocs() != 201 || mem.GetNumDeallocs() != 1 ) FAIL if( INSANE(s) || s.size() != 100 ) FAIL thrown = true; } if( !thrown ) FAIL //exception should have been thrown //if container didn't deal with the exception and clean up the allocated //memory then the leak detector will also trip later s.clear(); mem.Reset(140); mem.SetTripOnAlloc(); thrown = false; for( int i = 0; i < 70; i++ ){ s.insert( i ); } //now reset the allocator so it trips at a lower threshold //and test the copy mechanism works right mem.Reset( 50 ); mem.SetTripOnAlloc(); try{ set_t s2( s ); }catch( std::bad_alloc ){ if( mem.GetNumConstructs() != 50 ) FAIL if( mem.GetNumAllocs() != 51 ) FAIL if( mem.GetNumDestroys() != 50 ) FAIL if( mem.GetNumDeallocs() != 50 ) FAIL if( INSANE( s ) || s.size() != 70 ) FAIL thrown = true; } if( !thrown ) FAIL return( true ); }
bool assign_test( ) { bool rc = true; std::string s1( 5, 'x' ); const char *shrt_string = "Shorty"; const char *long_string = "This string is longer than 8 characters"; const std::string s2( shrt_string ); const std::string s3( long_string ); std::string s4( 5, 'x' ); std::string s5( 5, 'x' ); std::string s6( 5, 'x' ); std::string s7( 5, 'x' ); std::string s8( 5, 'x' ); std::string s9( 5, 'x' ); const char *raw = "This is a very, very long string"; s1 = s2; if( s1.size( ) != 6 || s1 != shrt_string || INSANE( s1 ) ) FAIL s1 = s3; if( s1.size( ) != 39 || s1 != long_string || INSANE( s1 ) ) FAIL s4 = shrt_string; if( s4.size( ) != 6 || s4 != shrt_string || INSANE( s4 ) ) FAIL s4 = long_string; if( s4.size( ) != 39 || s4 != long_string || INSANE( s4 ) ) FAIL s5 = 'y'; if( s5.size( ) != 1 || s5 != "y" || INSANE( s5 ) ) FAIL s6.assign( s3, 35, 5 ); if( s6.size( ) != 4 || s6 != "ters" || INSANE( s6 ) ) FAIL s6.assign( s3, 5, 16 ); if( s6.size( ) != 16 || s6 != "string is longer" || INSANE( s6 ) ) FAIL s7.assign( raw, 4 ); if( s7.size( ) != 4 || s7 != "This" || INSANE( s7 ) ) FAIL s7.assign( raw, 10 ); if( s7.size( ) != 10 || s7 != "This is a " || INSANE( s7 ) ) FAIL s8.assign( "Shorty" ); if( s8.size( ) != 6 || s8 != "Shorty" || INSANE( s8 ) ) FAIL s8.assign( long_string ); if( s8.size( ) != 39 || s8 != long_string || INSANE( s8 ) ) FAIL s9.assign( 7, 'x' ); if( s9.size( ) != 7 || s9 != "xxxxxxx" || INSANE( s9 ) ) FAIL s9.assign( 8, 'y' ); if( s9.size( ) != 8 || s9 != "yyyyyyyy" || INSANE( s9 ) ) FAIL return( rc ); }