first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / tests_structures / test_bit_vector.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : test_bit_vector                                                   *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 1991-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include <application/hoople_main.h>
16 #include <basis/array.h>
17 #include <basis/astring.h>
18 #include <basis/byte_array.h>
19 #include <basis/functions.h>
20 #include <basis/guards.h>
21 #include <loggers/combo_logger.h>
22 #include <mathematics/chaos.h>
23 #include <structures/bit_vector.h>
24 #include <structures/static_memory_gremlin.h>
25 #include <unit_test/unit_base.h>
26
27 #include <memory.h>
28 #include <stdlib.h>
29
30 using namespace application;
31 using namespace basis;
32 using namespace filesystem;
33 using namespace loggers;
34 using namespace mathematics;
35 using namespace structures;
36 using namespace textual;
37 using namespace timely;
38 using namespace unit_test;
39
40 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
41
42 #define MAX_TEST 100
43 #define FOOP_MAX 213
44
45 //////////////
46
47 class test_bit_vector : virtual public unit_base, virtual public application_shell
48 {
49 public:
50   test_bit_vector() : unit_base() {}
51   DEFINE_CLASS_NAME("test_bit_vector");
52   virtual int execute();
53 };
54
55 HOOPLE_MAIN(test_bit_vector, );
56
57 //////////////
58
59 struct test_struct { basis::un_int store; int posn; int size; };
60
61 int test_bit_vector::execute()
62 {
63   FUNCDEF("execute");
64   SETUP_COMBO_LOGGER;
65
66   const array<test_struct> unused;
67
68   chaos randomizer;
69   bit_vector foop(FOOP_MAX);
70
71   for (int i = 0; i < MAX_TEST; i++) {
72     // sets a random bit and finds that one.
73     int rando = randomizer.inclusive(0, FOOP_MAX-1);
74     foop.light(rando);
75     int found = foop.find_first(true);
76     ASSERT_EQUAL(found, rando, "find first locates first true");
77     foop.clear(rando);
78
79     foop.resize(FOOP_MAX);
80     ASSERT_EQUAL(0, foop.find_first(0), "locating location of first zero");
81     ASSERT_EQUAL(common::NOT_FOUND, foop.find_first(1), "showing there are no one bits");
82     for (int i = 0; i < 12; i++) foop.light(i);
83     ASSERT_EQUAL(12, foop.find_first(0), "finding first on partially set vector");
84
85     foop.light(FOOP_MAX);  // shouldn't work, but shouldn't die.
86     ASSERT_FALSE(foop.on(FOOP_MAX), "bit_on should not be lit past end of vector");
87
88     // sets a bunch of random bits.
89     for (int j = 0; j < 40; j++) {
90       int rando = randomizer.inclusive(0, FOOP_MAX-1);
91       foop.light(rando);
92     }
93     bit_vector foop2(FOOP_MAX, ((const byte_array &)foop).observe());
94     ASSERT_EQUAL(foop, foop2, "after lighting, vectors should be identical");
95
96     {
97       // this block tests the subvector and int storage/retrieval routines.
98       if (foop.bits() < 90) foop.resize(90);  // make sure we have room to play.
99
100       array<test_struct> tests;
101       test_struct t1 = { 27, 15, 5 };
102       tests += t1;
103       test_struct t2 = { 8, 25, 4 };
104       tests += t2;
105       test_struct t3 = { 1485, 34, 16 };
106       tests += t3;
107       test_struct t4 = { 872465, 50, 32 };
108       tests += t4;
109
110       for (int i = 0; i < tests.length(); i++) {
111         ASSERT_TRUE(foop.set(tests[i].posn, tests[i].size, tests[i].store),
112             "storing int in vector should work");
113
114 //hmmm: make this a test case!
115 //        bit_vector found = foop.subvector(tests[i].posn, tests[i].posn+tests[i].size-1);
116 //        LOG(astring(astring::SPRINTF, "contents found:\n%s", found.text_form().s()));
117
118         basis::un_int to_check = foop.get(tests[i].posn, tests[i].size);
119         if (to_check != tests[i].store)
120           LOG(a_sprintf("int found at %d in vector (%u) is different than what was stored (%u).",
121               i, to_check, tests[i].store));
122         ASSERT_EQUAL((int)to_check, (int)tests[i].store, "should see expected int stored in vector");
123       }
124     }
125
126     {
127       // tests random resizings and resettings.
128       int number_of_loops = randomizer.inclusive(50, 150);
129       for (int i = 0; i < number_of_loops; i++) {
130         int which_to_do = randomizer.inclusive(1, 3);
131         switch (which_to_do) {
132           case 1: {
133             // resize.
134             int new_size = randomizer.inclusive(0, 32000);
135             foop.resize(new_size);
136             break;
137           }
138           case 2: {
139             // reset.
140             int new_size = randomizer.inclusive(0, 32000);
141             foop.reset(new_size);
142             break;
143           }
144           case 3: {
145             // random sets.
146             int sets_to_do = randomizer.inclusive(40, 280);
147             for (int i = 0; i < sets_to_do; i++) {
148               int rando = randomizer.inclusive(0, foop.bits());
149               if (randomizer.inclusive(0, 1)) foop.light(rando);
150               else foop.clear(rando);
151             }
152             break;
153           }
154         }
155       }
156     }
157
158     foop.reset(FOOP_MAX);  // to clear before next loop.
159   }
160
161   return final_report();
162 }
163