From 031f61f31da0158c422623fce2a9aa3490392f10 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 5 Jan 2011 05:14:28 +0100 Subject: [PATCH] WIP prototypical Digxel implementation complete --- src/lib/time/digxel.hpp | 157 +++++++++++++++++---------------- tests/lib/time/digxel-test.cpp | 43 +++++---- 2 files changed, 109 insertions(+), 91 deletions(-) diff --git a/src/lib/time/digxel.hpp b/src/lib/time/digxel.hpp index 7d63770f9..2d99aa7fd 100644 --- a/src/lib/time/digxel.hpp +++ b/src/lib/time/digxel.hpp @@ -64,9 +64,11 @@ #include "lib/error.hpp" #include "lib/symbol.hpp" +#include "lib/util.hpp" #include #include +#include #include ///////////TODO #include #include @@ -75,11 +77,11 @@ namespace lib { namespace time { -// using std::string; + using std::string; namespace digxel { - using std::string; + using util::cStr; using lib::Literal; using boost::lexical_cast; @@ -117,17 +119,31 @@ namespace time { PrintfFormatter (Literal fmt) : printbuffer_() , formatSpec_(fmt) - { - printbuffer_[0] = '\0'; + { + clear(); } - void + void clear() { printbuffer_[0] = '\0'; } + bool empty() { return bool(*printbuffer_); } + + size_t + maxlen() const + { + return len; + } + + CBuf show (NUM val) { - size_t space = std::snprintf (printbuffer_, bufsiz, "%5d", val); - REQUIRE (space <= bufsiz, "Digxel value exceeded available buffer size. " - "For showing %s, %d chars instead of just %d would be required." - , lexical_cast(val), space, bufsiz); + if (empty()) + { + size_t space = std::snprintf (printbuffer_, bufsiz, formatSpec_, val); + REQUIRE (space < bufsiz, "Digxel value exceeded available buffer size. " + "For showing %s, %lu chars instead of just %d would be required." + , cStr(lexical_cast(val)), space, bufsiz); ///////////TICKET #197 + } + ENSURE (!empty()); + return printbuffer_; } }; @@ -149,61 +165,10 @@ namespace time { Formatter() : PrintfFormatter("%06.3f") { } }; - - /** - * The outward hull of a concrete Digxel implementation. - * Inheriting from the Digxel interface, it embodies a concrete - * Formatter specialised to yield the desired behaviour. - * - * @param TODO - * @todo WIP-WIP-WIP - */ - template< typename NUM - , class FMT - > - class Holder - { - protected: - FMT buffer_; - NUM value_; - - - /* === Digxel implementation === */ - int - getIntValue() const - { - return ValTrait::asInt (value_); - } - - CBuf - getFormatted() - { - UNIMPLEMENTED("call formatting or cache"); - } -// -// void -// changeTo (int i) -// { -// UNIMPLEMENTED("mutate INT"); -// } -// -// void -// changeTo (double d) -// { -// UNIMPLEMENTED("mutate FLOAT"); -// } - - - public: - Holder () - : buffer_() - , value_() - { } - - }; } //(End) digxel configuration namespace + /** * A number element for building structured numeric displays. * The purpose is to represent parts of a numeric format, like @@ -222,32 +187,74 @@ namespace time { , class FMT = digxel::Formatter > class Digxel - : public digxel::Holder - , public boost::totally_ordered, - boost::totally_ordered, NUM - > > + : public boost::totally_ordered > +// , +// boost::totally_ordered, NUM +// > > { - typedef digxel::Holder _Holder; + mutable + FMT buffer_; + NUM value_; - typedef const char* CBuf; + static NUM use_newValue_as_is (NUM n) { return n; } + typedef std::tr1::function _Mutator; public: + /** a functor to be applied on any new digxel value. + * This allows individual instances to limit the possible digxel values, + * or to update an compound value (e.g. a time comprised of hour, minute + * and second digxel elements). By default, new values can be set without + * any restrictions or side effects. + */ + _Mutator mutator; - operator int() const { return getIntValue(); } - CBuf show() { return getFormatted(); } + Digxel () + : buffer_() + , value_() + , mutator(use_newValue_as_is) + { } + + // using the standard copy operations + + operator NUM() const { return value_; } + operator string() const { return show(); } + + size_t maxlen() const { return buffer_.maxlen(); } + + digxel::CBuf + show() const + { + return buffer_.show (value_); + } + + + void + operator= (NUM n) + { + NUM changedValue = mutator(n); + this->setValueRaw (changedValue); + } + + void + setValueRaw (NUM newVal) + { + if (newVal != value_) + { + value_ = newVal; + buffer_.clear(); + } + } + //---Supporting-totally_ordered--------- bool operator< (Digxel const& o) const { return value_ < NUM(o); } bool operator== (Digxel const& o) const { return value_ == NUM(o); } - bool operator== (NUM n) const { return value_ == n ; } - bool operator< (NUM n) const { return value_ < n ; } - bool operator> (NUM n) const { return value_ > n ; } +// bool operator== (NUM n) const { return value_ == n ; } +// bool operator< (NUM n) const { return value_ < n ; } +// bool operator> (NUM n) const { return value_ > n ; } - protected: - virtual int getIntValue() const =0; - virtual CBuf getFormatted() =0; }; diff --git a/tests/lib/time/digxel-test.cpp b/tests/lib/time/digxel-test.cpp index 5a76553f3..16c94d21f 100644 --- a/tests/lib/time/digxel-test.cpp +++ b/tests/lib/time/digxel-test.cpp @@ -28,7 +28,7 @@ //#include //#include -#include +//#include #include //TODO #include @@ -49,9 +49,6 @@ namespace test{ namespace { // Test data - // Placeholder to mark the function argument in a "lambda-expression" - boost::lambda::placeholder1_type _1_; - const uint REPEAT = 40; const uint RAND_RANGE = 100; const uint RAND_DENOM = 3; @@ -65,6 +62,21 @@ namespace test{ return arbitrary; } + inline uint + isOdd (uint i) + { + return i % 2; + } + + double sum(0), + checksum(0); + + double + sideeffectSum (double val) + { + sum += val; + return val; + } /* === special Digxel configuration for this test === */ @@ -78,11 +90,12 @@ namespace test{ struct VerySpecialFormat + : digxel::PrintfFormatter { - + VerySpecialFormat() : digxel::PrintfFormatter("## %4.1f ##") { } }; - typedef digxel::Holder TestDigxel; + typedef Digxel TestDigxel; } @@ -114,11 +127,11 @@ namespace test{ { TestDigxel digi; CHECK (0 == digi); - CHECK ("## 0 ##" == digi.show()); + CHECK ("## 0 ##" == string(digi)); digi = 88; CHECK (88 == digi); - CHECK ("## 88.0 ##" == digi.show()); + CHECK ("## 88.0 ##" == string(digi)); } @@ -127,10 +140,9 @@ namespace test{ { TestDigxel digi; - uint sum(0), checksum(0); - // configure what the Digxel does on "mutation" - digi.mutator = ( var(sum) += _1_ ); + digi.mutator = sideeffectSum; + sum = checksum = 0; CHECK (0 == digi); for (uint i=0; i < REPEAT; ++i) @@ -176,7 +188,7 @@ namespace test{ d1 = someValue; CHECK (d1 == someValue); - TextDigxel d2(d1); + TestDigxel d2(d1); CHECK (d2 == someValue); CHECK (!isSameObject (d1, d2)); @@ -192,7 +204,7 @@ namespace test{ TestDigxel digi; digi = 123456789.12345678; - string formatted (digi.show()); // should trigger assertion + string formatted (digi); // should trigger assertion CHECK (formatted.length() <= digi.maxlen()); } @@ -207,8 +219,8 @@ namespace test{ start = clock(); for (uint i=0; i < TIMING_CNT; ++i) { - val odd = i % 2; digi = 1; + isOdd (i); } stop = clock(); uint without_reformatting = stop - start; @@ -217,8 +229,7 @@ namespace test{ start = clock(); for (uint i=0; i < TIMING_CNT; ++i) { - val odd = i % 2; - digi = odd; + digi = isOdd (i); } stop = clock(); uint with_reformatting = stop - start;