From c986a2add25920eabacfd620a1a2132cd7e4981d Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Sat, 11 Sep 2010 13:06:10 -0700 Subject: [PATCH] Add support for uint64_t to pmt. --- gruel/src/include/gruel/pmt.h | 21 ++++++++++++++ gruel/src/lib/pmt/pmt.cc | 47 +++++++++++++++++++++++++++++++ gruel/src/lib/pmt/pmt_int.h | 14 +++++++++ gruel/src/lib/pmt/pmt_io.cc | 2 ++ gruel/src/lib/pmt/qa_pmt_prims.cc | 13 +++++++++ gruel/src/lib/pmt/qa_pmt_prims.h | 2 ++ 6 files changed, 99 insertions(+) diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h index c371b023..514b24d8 100644 --- a/gruel/src/include/gruel/pmt.h +++ b/gruel/src/include/gruel/pmt.h @@ -163,6 +163,27 @@ pmt_t pmt_from_long(long x); */ long pmt_to_long(pmt_t x); +/* + * ------------------------------------------------------------------------ + * uint64_t + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is an uint64 number, else false +bool pmt_is_uint64(pmt_t x); + +//! Return the pmt value that represents the uint64 \p x. +pmt_t pmt_from_uint64(uint64_t x); + +/*! + * \brief Convert pmt to uint64 if possible. + * + * When \p x represents an exact integer that fits in a uint64, + * return that uint64. Else raise an exception, either wrong_type + * when x is not an exact uint64, or out_of_range when it doesn't fit. + */ +uint64_t pmt_to_uint64(pmt_t x); + /* * ------------------------------------------------------------------------ * Reals diff --git a/gruel/src/lib/pmt/pmt.cc b/gruel/src/lib/pmt/pmt.cc index aa1688d2..f9cf6b4b 100644 --- a/gruel/src/lib/pmt/pmt.cc +++ b/gruel/src/lib/pmt/pmt.cc @@ -105,6 +105,12 @@ _integer(pmt_t x) return dynamic_cast(x.get()); } +static pmt_uint64 * +_uint64(pmt_t x) +{ + return dynamic_cast(x.get()); +} + static pmt_real * _real(pmt_t x) { @@ -304,6 +310,40 @@ pmt_to_long(pmt_t x) throw pmt_wrong_type("pmt_to_long", x); } +//////////////////////////////////////////////////////////////////////////// +// Uint64 +//////////////////////////////////////////////////////////////////////////// + +pmt_uint64::pmt_uint64(uint64_t value) : d_value(value) {} + +bool +pmt_is_uint64(pmt_t x) +{ + return x->is_uint64(); +} + + +pmt_t +pmt_from_uint64(uint64_t x) +{ + return pmt_t(new pmt_uint64(x)); +} + +uint64_t +pmt_to_uint64(pmt_t x) +{ + if(x->is_uint64()) + return _uint64(x)->value(); + if(x->is_integer()) + { + long tmp = _integer(x)->value(); + if(tmp >= 0) + return (uint64_t) tmp; + } + + throw pmt_wrong_type("pmt_to_uint64", x); +} + //////////////////////////////////////////////////////////////////////////// // Real //////////////////////////////////////////////////////////////////////////// @@ -929,6 +969,9 @@ pmt_eqv(const pmt_t& x, const pmt_t& y) if (x->is_integer() && y->is_integer()) return _integer(x)->value() == _integer(y)->value(); + if (x->is_uint64() && y->is_uint64()) + return _uint64(x)->value() == _uint64(y)->value(); + if (x->is_real() && y->is_real()) return _real(x)->value() == _real(y)->value(); @@ -947,6 +990,9 @@ pmt_eqv_raw(pmt_base *x, pmt_base *y) if (x->is_integer() && y->is_integer()) return _integer(x)->value() == _integer(y)->value(); + if (x->is_uint64() && y->is_uint64()) + return _uint64(x)->value() == _uint64(y)->value(); + if (x->is_real() && y->is_real()) return _real(x)->value() == _real(y)->value(); @@ -1328,6 +1374,7 @@ pmt_dump_sizeof() printf("sizeof(pmt_bool) = %3zd\n", sizeof(pmt_bool)); printf("sizeof(pmt_symbol) = %3zd\n", sizeof(pmt_symbol)); printf("sizeof(pmt_integer) = %3zd\n", sizeof(pmt_integer)); + printf("sizeof(pmt_uint64) = %3zd\n", sizeof(pmt_uint64)); printf("sizeof(pmt_real) = %3zd\n", sizeof(pmt_real)); printf("sizeof(pmt_complex) = %3zd\n", sizeof(pmt_complex)); printf("sizeof(pmt_null) = %3zd\n", sizeof(pmt_null)); diff --git a/gruel/src/lib/pmt/pmt_int.h b/gruel/src/lib/pmt/pmt_int.h index 50683ffb..ea28e37b 100644 --- a/gruel/src/lib/pmt/pmt_int.h +++ b/gruel/src/lib/pmt/pmt_int.h @@ -47,6 +47,7 @@ public: virtual bool is_symbol() const { return false; } virtual bool is_number() const { return false; } virtual bool is_integer() const { return false; } + virtual bool is_uint64() const { return false; } virtual bool is_real() const { return false; } virtual bool is_complex() const { return false; } virtual bool is_null() const { return false; } @@ -118,6 +119,19 @@ public: long value() const { return d_value; } }; +class pmt_uint64 : public pmt_base +{ +public: + uint64_t d_value; + + pmt_uint64(uint64_t value); + //~pmt_uint64(){} + + bool is_number() const { return true; } + bool is_uint64() const { return true; } + uint64_t value() const { return d_value; } +}; + class pmt_real : public pmt_base { public: diff --git a/gruel/src/lib/pmt/pmt_io.cc b/gruel/src/lib/pmt/pmt_io.cc index 179e6b72..b909c1b6 100644 --- a/gruel/src/lib/pmt/pmt_io.cc +++ b/gruel/src/lib/pmt/pmt_io.cc @@ -64,6 +64,8 @@ pmt_write(pmt_t obj, std::ostream &port) else if (pmt_is_number(obj)){ if (pmt_is_integer(obj)) port << pmt_to_long(obj); + else if (pmt_is_uint64(obj)) + port << pmt_to_uint64(obj); else if (pmt_is_real(obj)) port << pmt_to_double(obj); else if (pmt_is_complex(obj)){ diff --git a/gruel/src/lib/pmt/qa_pmt_prims.cc b/gruel/src/lib/pmt/qa_pmt_prims.cc index f2414c72..985361f1 100644 --- a/gruel/src/lib/pmt/qa_pmt_prims.cc +++ b/gruel/src/lib/pmt/qa_pmt_prims.cc @@ -103,6 +103,19 @@ qa_pmt_prims::test_integers() CPPUNIT_ASSERT_EQUAL(1L, pmt_to_long(p1)); } +void +qa_pmt_prims::test_uint64s() +{ + pmt_t p1 = pmt_from_uint64((uint64_t)1); + pmt_t m1 = pmt_from_uint64((uint64_t)8589934592ULL); + CPPUNIT_ASSERT(!pmt_is_uint64(PMT_T)); + CPPUNIT_ASSERT(pmt_is_uint64(p1)); + CPPUNIT_ASSERT(pmt_is_uint64(m1)); + CPPUNIT_ASSERT_THROW(pmt_to_uint64(PMT_T), pmt_wrong_type); + CPPUNIT_ASSERT_EQUAL((uint64_t)8589934592ULL, (uint64_t)pmt_to_uint64(m1)); + CPPUNIT_ASSERT_EQUAL((uint64_t)1ULL, (uint64_t)pmt_to_uint64(p1)); +} + void qa_pmt_prims::test_reals() { diff --git a/gruel/src/lib/pmt/qa_pmt_prims.h b/gruel/src/lib/pmt/qa_pmt_prims.h index 29ba02f1..efc5c605 100644 --- a/gruel/src/lib/pmt/qa_pmt_prims.h +++ b/gruel/src/lib/pmt/qa_pmt_prims.h @@ -31,6 +31,7 @@ class qa_pmt_prims : public CppUnit::TestCase { CPPUNIT_TEST(test_symbols); CPPUNIT_TEST(test_booleans); CPPUNIT_TEST(test_integers); + CPPUNIT_TEST(test_uint64s); CPPUNIT_TEST(test_reals); CPPUNIT_TEST(test_complexes); CPPUNIT_TEST(test_pairs); @@ -52,6 +53,7 @@ class qa_pmt_prims : public CppUnit::TestCase { void test_symbols(); void test_booleans(); void test_integers(); + void test_uint64s(); void test_reals(); void test_complexes(); void test_pairs(); -- 2.39.5