aboutsummaryrefslogtreecommitdiff
path: root/src/jtutil/util++2.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/jtutil/util++2.hh')
-rw-r--r--src/jtutil/util++2.hh119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/jtutil/util++2.hh b/src/jtutil/util++2.hh
new file mode 100644
index 0000000..9c37159
--- /dev/null
+++ b/src/jtutil/util++2.hh
@@ -0,0 +1,119 @@
+// util++.hh -- stuff for my C++ utility library
+// $Id$
+//
+// jtutil::{min,max} - min/max templates
+// jtutil::abs - absolute value template
+// jtutil::pow* - raise floating point value to small-integer power
+// fuzzy::<fpt> - fuzzy floating point comparisons and other operations
+// round::<fpt> - floating point rounding
+//
+
+//******************************************************************************
+
+namespace jtutil
+ {
+
+// how many integers are in the closed interval [low,high]
+inline int how_many_in_range(int low, int high)
+ { return high - low + 1; }
+
+//
+// minimum/maximum templates (valid for both integer and floating-point types)
+// FIXME: these are supposed to be in the STL,
+// but in practice they often aren't (yet) :(
+// eg the gcc 2.95.2 library doesn't have them :(
+//
+template <typename num>
+ inline num min(num x, num y) { return x < y ? x : y; };
+template <typename num>
+ inline num max(num x, num y) { return x > y ? x : y; };
+
+//
+// absolute value template
+// FIXME: this ought to be somewhere in the STL?
+//
+template <typename fpt>
+ inline fpt abs(fpt x) { return (x > 0.0) ? x : -x; }
+
+//
+// These functions raise their arguments (presumably floating-point)
+// to various small-integer powers.
+// FIXME: do we ever use these?
+//
+template <typename fpt>
+ inline fpt pow2(fpt x) { return x*x; }
+template <typename fpt>
+ inline fpt pow3(fpt x) { return x*x*x; }
+template <typename fpt>
+ inline fpt pow4(fpt x) { return pow2(pow2(x)); }
+template <typename fpt>
+ inline fpt pow5(fpt x) { return x * pow4(x); }
+template <typename fpt>
+ inline fpt pow6(fpt x) { return pow3(pow2(x)); }
+template <typename fpt>
+ inline fpt pow7(fpt x) { return x * pow6(x); }
+template <typename fpt>
+ inline fpt pow8(fpt x) { return pow2(pow2(pow2(x))); }
+
+ // close namespace jtutil::
+ };
+
+//******************************************************************************
+
+//
+// This template does fuzzy comparisons and related operations on
+// floating point values, parameterized by the floating point type.
+//
+// The fuzzy comparison semantics are based on those of APL, but are
+// modified to use an absolute error tolerance for values close to 0.
+//
+
+// this template class has only static members
+// ... it's a class, not a namespace, because we want to express the
+// semantics that the entire class is a single template, rather
+// than the individual members being conceptually-unrelated templates
+// ... moreover, we need the *data* member (template) tolerance , and
+// it seems C++ doesn't grok data templates which aren't in a class
+template <class fpt>
+class fuzzy
+ {
+public:
+ // comparison tolerance
+ // ... must be explicitly initialized when instantiating
+ // for a new <fpt> type, see "fuzzy.cc" for details/examples
+ // ... may be modified by user code if needed
+ static fpt tolerance;
+
+ // fuzzy commparisons
+ static bool EQ(fpt x, fpt y);
+ static bool NE(fpt x, fpt y) { return ! EQ(x,y); }
+ static bool LT(fpt x, fpt y) { return EQ(x,y) ? false : (x < y); }
+ static bool LE(fpt x, fpt y) { return EQ(x,y) ? true : (x < y); }
+ static bool GT(fpt x, fpt y) { return EQ(x,y) ? false : (x > y); }
+ static bool GE(fpt x, fpt y) { return EQ(x,y) ? true : (x > y); }
+
+ static bool is_integer(fpt x); // is x fuzzily an integer?
+ static int floor(fpt x); // round x fuzzily down to integer
+ static int ceiling(fpt x); // round x fuzzily up to integer
+ };
+
+//******************************************************************************
+
+//
+// This template does machine-independent rounding of floating point
+// values, parameterized by the floating point type.
+//
+
+// this template class has only static members
+// ... it's a class, not a namespace, because we want to express the
+// semantics that the entire class is a single template, rather
+// than the individual members being conceptually-unrelated templates
+template <class fpt>
+class round
+ {
+public:
+ static int to_integer(fpt x); // round to nearest integer
+
+ static int floor(fpt x); // round down to integer
+ static int ceiling(fpt x); // round up to integer
+ };