From d8fd737fb9ca867f53a287de1c4a87f16a6834f7 Mon Sep 17 00:00:00 2001 From: Morgan Deters Date: Tue, 14 Aug 2012 20:08:29 +0000 Subject: [PATCH] Fixes to integer wrapper classes: * more uniform interface between the CLN and GMP wrappers * support base inference (base == 0) on parsing strings with the CLN wrapper; this was a difference from the GMP wrapper (resolves bug #372) --- src/util/integer_cln_imp.h | 64 +++++++++++++++++---------- src/util/integer_gmp_imp.h | 4 +- test/unit/util/integer_black.h | 20 +++++++++ test/unit/util/subrange_bound_white.h | 4 +- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h index 71d6d5b6d..8f7daf4f5 100644 --- a/src/util/integer_cln_imp.h +++ b/src/util/integer_cln_imp.h @@ -58,6 +58,42 @@ private: //Integer(const mpz_class& val) : d_value(val) {} Integer(const cln::cl_I& val) : d_value(val) {} + void readInt(const cln::cl_read_flags& flags, const std::string& s, unsigned base) throw(std::invalid_argument) { + try { + d_value = read_integer(flags, s.c_str(), NULL, NULL); + } catch(...) { + std::stringstream ss; + ss << "Integer() failed to parse value \"" << s << "\" in base " << base; + throw std::invalid_argument(ss.str()); + } + } + + void parseInt(const std::string& s, unsigned base) throw(std::invalid_argument) { + cln::cl_read_flags flags; + flags.syntax = cln::syntax_integer; + flags.lsyntax = cln::lsyntax_standard; + flags.rational_base = base; + if(base == 0) { + // infer base in a manner consistent with GMP + if(s[0] == '0') { + flags.lsyntax = cln::lsyntax_commonlisp; + std::string st = s; + if(s[1] == 'X' || s[1] == 'x') { + st.replace(0, 2, "#x"); + } else if(s[1] == 'B' || s[1] == 'b') { + st.replace(0, 2, "#b"); + } else { + st.replace(0, 1, "#o"); + } + readInt(flags, st, base); + return; + } else { + flags.rational_base = 10; + } + } + readInt(flags, s, base); + } + public: /** Constructs a rational with the value 0. */ @@ -69,32 +105,12 @@ public: * For more information about what is a valid rational string, * see GMP's documentation for mpq_set_str(). */ - explicit Integer(const char * s, int base = 10) throw (std::invalid_argument){ - cln::cl_read_flags flags; - flags.syntax = cln::syntax_integer; - flags.lsyntax = cln::lsyntax_standard; - flags.rational_base = base; - try{ - d_value = read_integer(flags, s, NULL, NULL); - }catch(...){ - std::stringstream ss; - ss << "Integer() failed to parse value \"" <