]> Dogcows Code - chaz/vimcoder/blobdiff - src/com/dogcows/resources/C++Driver
separate whitespace handling into its own function
[chaz/vimcoder] / src / com / dogcows / resources / C++Driver
index 9f25901fbdc34f972dc761abade4a17df0a0a704..24ab333609ffa5ed8a51c9c80f0b32943fe2fb19 100644 (file)
@@ -1,21 +1,28 @@
 
 #include "$CLASSNAME$.cc"
 
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+#include <fstream>
 #include <iostream>
 #include <sstream>
+#include <string>
 #include <sys/time.h>
+#include <vector>
 
-static bool            __exit_on_fail = false;
-static int             __pass = 0;
-static int             __fail = 0;
-static double  __time = 0.0;
+using namespace std;
+
+
+const static double __EPSILON = 1e-9;
+static double __time = 0.0;
 
 static void __timer_start()
 {
        struct timeval tv;
        if (gettimeofday(&tv, NULL) == 0)
        {
-               __time = (double)tv.tv_sec + (double)tv.tv_usec * 0.000001;
+               __time = double(tv.tv_sec) + double(tv.tv_usec) * 0.000001;
        }
 }
 
@@ -26,76 +33,162 @@ static double __timer_stop()
        return __time - start;
 }
 
-template <class T>
-std::string __encode(const T& in)
+
+static void __eat_whitespace(std::istream& in)
 {
-       std::ostringstream s;
-       s << in;
-       return s.str();
+       while (in.good() && std::isspace(in.peek())) in.get();
 }
 
-std::string __encode(const std::string& in)
+
+std::ostream& operator << (std::ostream& out, const std::string& str)
 {
-       std::ostringstream s;
-       s << '"' << in << '"';
-       return s.str();
+       out << '"' << str.c_str() << '"';
+       return out;
 }
 
 template <class T>
-std::string __join(const std::vector<T>& in, const std::string& glue)
+std::ostream& operator << (std::ostream& out, const std::vector<T>& vec)
 {
-       if (in.size() == 0) return "";
-       std::ostringstream s;
-       s << __encode(in[0]);
-       for (size_t i = 1; i < in.size(); ++i) s << glue << __encode(in[i]);
-       return s.str();
+       out << '{';
+       if (0 < vec.size())
+       {
+               out << vec[0];
+               for (size_t i = 1; i < vec.size(); ++i) out << ", " << vec[i];
+       }
+       out << '}';
+       return out;
+}
+
+std::istream& operator >> (std::istream& in, std::string& str)
+{
+       __eat_whitespace(in);
+
+       int c;
+       if (in.good() && (c = in.get()) == '"')
+       {
+               std::ostringstream s;
+               while (in.good() && (c = in.get()) != '"')
+               {
+                       s.put(char(c));
+               }
+               str = s.str();
+       }
+
+       return in;
 }
 
 template <class T>
-std::string __encode(const std::vector<T>& in)
+std::istream& operator >> (std::istream& in, std::vector<T>& vec)
 {
-       std::ostringstream s;
-       s << "{ " << __join(in, ",  ") << " }";
-       return s.str();
+       __eat_whitespace(in);
+
+       int c;
+       if (in.good() && (c = in.get()) == '{')
+       {
+               __eat_whitespace(in);
+               vec.clear();
+               while (in.good() && (c = in.get()) != '}')
+               {
+                       if (c != ',') in.putback(c);
+
+                       T t;
+                       in >> t;
+                       __eat_whitespace(in);
+
+                       vec.push_back(t);
+               }
+       }
+
+       return in;
 }
 
-void __do_test(const std::string& expected, $METHODPARAMS$)
+
+template <class T>
+bool __equals(const T& actual, const T& expected)
 {
-       static int testNum = 0;
-       std::cout << "----------------------------------------" << std::endl
-                         << "Test " << testNum++ << ": ";
+       return actual == expected;
+}
 
-       __timer_start();
-       
-       $CLASSNAME$ object;
-       $RETURNTYPE$ ret = object.$METHODNAME$($METHODPARAMNAMES$);
-       
-       double t = __timer_stop();
-       
-       std::string actual = __encode(ret);
-       if (actual == expected)
+bool __equals(double actual, double expected)
+{
+       if (std::abs(actual - expected) < __EPSILON)
        {
-               std::cout << "[PASS] in " << t << " seconds." << std::endl;
-               ++__pass;
+               return true;
        }
        else
        {
-               std::cout << "[FAIL] in " << t << " seconds." << std::endl
-                                 << "   Actual: " << actual << std::endl
-                                 << " Expected: " << expected << std::endl;
-               ++__fail;
-               if (__exit_on_fail) exit(1);
+               double minimum = std::min(expected * (1.0 - __EPSILON), expected * (1.0 + __EPSILON));
+               double maximum = std::max(expected * (1.0 - __EPSILON), expected * (1.0 + __EPSILON));
+               return actual > minimum && actual < maximum;
        }
 }
 
+bool __equals(const std::vector<double>& actual, const std::vector<double>& expected)
+{
+       if (actual.size() != expected.size())
+               return false;
+
+       for (size_t i = 0; i < actual.size(); ++i)
+               if (!__equals(actual[i], expected[i]))
+                       return false;
+
+       return true;
+}
+
+
 int main(int argc, char* argv[])
 {
+       bool    __exit_on_fail = false;
+       int     __pass = 0;
+       int     __fail = 0;
+
        if (1 < argc) __exit_on_fail = true;
 
-$TESTCASES$
+       std::ifstream __in("testcases.txt");
+       for(;;)
+       {
+               $RETURNTYPE$    __expected;
+               $METHODPARAMDECLARES$
+               __in >> __expected >> $METHODPARAMSTREAMIN$;
+               if (!__in.good()) break;
+
+               std::cout << "----------------------------------------" << std::endl
+                         << "Test " << (__pass + __fail) << ": ";
+               std::cout.flush();
+
+               __timer_start();
+
+               $CLASSNAME$ object;
+               $RETURNTYPE$ __actual = object.$METHODNAME$($METHODPARAMNAMES$);
+
+               double __t = __timer_stop();
+
+               if (__equals(__actual, __expected))
+               {
+                       std::cout << "[PASS] in " << __t << " seconds." << std::endl;
+                       ++__pass;
+               }
+               else
+               {
+                       std::cout << "[FAIL] in " << __t << " seconds." << std::endl
+                                 << "->  Input: " << $METHODPARAMSTREAMOUT$ << std::endl
+                                 << "   Actual: " << __actual << std::endl
+                                 << " Expected: " << __expected << std::endl;
+                       ++__fail;
+                       if (__exit_on_fail) exit(1);
+               }
+       }
+
        std::cout << "========================================" << std::endl
-                         << " Total Pass: " << __pass << std::endl
-                         << " Total Fail: " << __fail << std::endl;
+                 << " Total Pass: " << __pass << std::endl
+                 << " Total Fail: " << __fail << std::endl;
+
+       if (__fail == 0)
+       {
+               std::cout << std::endl << "Nice!  "
+                         << "Don't forget to compile remotely before submitting."
+                         << std::endl;
+       }
 
        return __fail;
 }
This page took 0.030315 seconds and 4 git commands to generate.