t_list.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : test_list                                                         *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 1993-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #include <basis/chaos.h>
00016 #include <basis/guards.h>
00017 #include <basis/istring.h>
00018 #include <nodes/list.h>
00019 #include <nodes/node.h>
00020 #include <loggers/file_logger.h>
00021 #include <opsystem/path_configuration.h>
00022 #include <data_struct/static_memory_gremlin.h>
00023 
00024 HOOPLE_STARTUP_CODE;
00025 
00026 using namespace nodes;
00027 
00028 #define DEBUG_LIST
00029   // uncomment this line to get more debugging output (into a file called
00030   // LOGFILE_NAME).
00031 
00032 const istring LOGFILE_NAME =  path_configuration::make_logfile_name
00033     ("t_list.log");
00034   // the name of our logging file.
00035 
00036 const int DEFAULT_ITERATIONS = 5000;
00037   // the default number of times we run through our phase loop.
00038 
00039 typedef basket<int> t_node;
00040   // the object we store in the list, a templated integer.
00041 
00042 #define CASTER(bare_node) static_cast<const t_node *>(bare_node)
00043   // turns a node pointer into our special t_node.
00044 
00045 int main(int formal(argc), char *formal(argv)[])
00046 {
00047   list the_list;
00048   chaos randomizer;
00049 
00050   int iterations_left = DEFAULT_ITERATIONS;
00051   while (iterations_left-- > 0) {
00052 
00053     // run through the phases below as many times as we are told.
00054 
00055     {
00056       // phase for adding a random number into the list.
00057       int to_add = randomizer.inclusive(0, 100000);
00058 
00059       // seek the correct insertion place to keep the list ordered.
00060       list::iterator iter = the_list.head();
00061       while (!iter.is_tail() && iter.observe()
00062           && (CASTER(iter.observe())->stored() <= to_add) )
00063         iter++;
00064       the_list.insert(iter, new t_node(2, to_add));
00065     }
00066 
00067     {
00068       // test the list invariant (which is that all elements should be sorted
00069       // in non-decreasing order).
00070       list::iterator iter = the_list.tail();
00071       // initialize our comparator.
00072       int bigger = CASTER(iter.observe())->stored();
00073       // loop backwards until we hit the head.
00074       while (!iter.is_head()) {
00075         // check that the last value is not less than the current value.
00076         if (bigger < CASTER(iter.observe())->stored())
00077           deadly_error("t_list", "invariant check",
00078               "found a mal-ordering in the list");
00079         bigger = CASTER(iter.observe())->stored();
00080         iter--;
00081       }
00082     }
00083 
00084     {
00085       // if the conditions are favorable, we whack at least one element out of
00086       // the list.
00087       if (randomizer.inclusive(1, 100) < 20) {
00088         int elem = the_list.elements();
00089         int to_whack = randomizer.inclusive(0, elem - 1);
00090         
00091         // start at the head of the list...
00092         list::iterator iter = the_list.head();
00093         // and jump to the element we chose.
00094         the_list.forward(iter, to_whack);
00095         if (the_list.index(iter) != to_whack)
00096           deadly_error("t_list", "forward check",
00097               "logic error: index of element to zap is incorrect");
00098         if (iter.is_tail())
00099           deadly_error("t_list", "forward check",
00100               "logic error: got to the tail somehow");
00101         the_list.zap(iter);
00102       }
00103     }
00104 
00105   }
00106 
00107 #ifdef DEBUG_LIST
00108   list::iterator iter = the_list.head();
00109   file_logger log(LOGFILE_NAME);
00110   log.log("");
00111   log.log("list contents:");
00112   int indy = 0;
00113   while (!iter.is_tail()) {
00114     int item = CASTER(iter.observe())->stored();
00115     log.log(istring(istring::SPRINTF, "item #%d: %d", indy, item));
00116     indy++;
00117     iter++;
00118   }
00119 #endif
00120 
00121   guards::alert_message("list:: works for those functions tested.");
00122   return 0;
00123 }
00124 

Generated on Fri Nov 21 04:30:12 2008 for HOOPLE Libraries by  doxygen 1.5.1