From 8fdf123fe6dac43ad7b8020d7bb7446c51cf75e7 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 16 Oct 2008 15:43:32 +0400 Subject: [PATCH] symbol: make get_domain() a virtual method, remove symbol::domain. This cuts yet another 4 bytes from GiNaC::symbol. While at it, fix a memory leak in ginsh. --- ginac/symbol.cpp | 56 ++++++++++++++------------------------------ ginac/symbol.h | 55 +++++++++++++++---------------------------- ginsh/ginsh.h | 2 +- ginsh/ginsh_lexer.ll | 8 +++++-- 4 files changed, 43 insertions(+), 78 deletions(-) diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp index a1c15ed1..9a729919 100644 --- a/ginac/symbol.cpp +++ b/ginac/symbol.cpp @@ -45,25 +45,18 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(symbol, basic, // symbol -symbol::symbol() - : serial(next_serial++), name(""), TeX_name(""), domain(domain::complex) +symbol::symbol() : serial(next_serial++), name(""), TeX_name("") { setflag(status_flags::evaluated | status_flags::expanded); } // realsymbol -realsymbol::realsymbol() -{ - domain = domain::real; -} +realsymbol::realsymbol() : symbol() { } // possymbol -possymbol::possymbol() -{ - domain = domain::positive; -} +possymbol::possymbol() : realsymbol() { } ////////// // other constructors @@ -73,34 +66,31 @@ possymbol::possymbol() // symbol -symbol::symbol(const std::string & initname, unsigned domain) : - serial(next_serial++), name(initname), TeX_name(""), - domain(domain) +symbol::symbol(const std::string & initname) : serial(next_serial++), + name(initname), TeX_name("") { setflag(status_flags::evaluated | status_flags::expanded); } -symbol::symbol(const std::string & initname, const std::string & texname, unsigned domain) : - serial(next_serial++), name(initname), TeX_name(texname), domain(domain) +symbol::symbol(const std::string & initname, const std::string & texname) : + serial(next_serial++), name(initname), TeX_name(texname) { setflag(status_flags::evaluated | status_flags::expanded); } // realsymbol -realsymbol::realsymbol(const std::string & initname, unsigned domain) - : symbol(initname, domain) { } +realsymbol::realsymbol(const std::string & initname) : symbol(initname) { } -realsymbol::realsymbol(const std::string & initname, const std::string & texname, unsigned domain) - : symbol(initname, texname, domain) { } +realsymbol::realsymbol(const std::string & initname, const std::string & texname) + : symbol(initname, texname) { } // possymbol -possymbol::possymbol(const std::string & initname, unsigned domain) - : symbol(initname, domain) { } +possymbol::possymbol(const std::string & initname) : realsymbol(initname) { } -possymbol::possymbol(const std::string & initname, const std::string & texname, unsigned domain) - : symbol(initname, texname, domain) { } +possymbol::possymbol(const std::string & initname, const std::string & texname) + : realsymbol(initname, texname) { } ////////// // archiving @@ -114,8 +104,6 @@ symbol::symbol(const archive_node &n, lst &sym_lst) name = std::string(""); if (!n.find_string("TeXname", TeX_name)) TeX_name = std::string(""); - if (!n.find_unsigned("domain", domain)) - domain = domain::complex; setflag(status_flags::evaluated | status_flags::expanded); } @@ -144,8 +132,6 @@ void symbol::archive(archive_node &n) const n.add_string("name", name); if (!TeX_name.empty()) n.add_string("TeX_name", TeX_name); - if (domain != domain::complex) - n.add_unsigned("domain", domain); } ////////// @@ -180,7 +166,7 @@ void symbol::do_print_tree(const print_tree & c, unsigned level) const c.s << std::string(level, ' ') << name << " (" << class_name() << ")" << " @" << this << ", serial=" << serial << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec - << ", domain=" << domain + << ", domain=" << get_domain() << std::endl; } @@ -209,10 +195,10 @@ bool symbol::info(unsigned inf) const case info_flags::expanded: return true; case info_flags::real: - return domain == domain::real || domain == domain::positive; + return get_domain() == domain::real || get_domain() == domain::positive; case info_flags::positive: case info_flags::nonnegative: - return domain == domain::positive; + return get_domain() == domain::positive; case info_flags::has_indices: return false; } @@ -221,24 +207,16 @@ bool symbol::info(unsigned inf) const ex symbol::conjugate() const { - if (this->domain == domain::complex) { - return conjugate_function(*this).hold(); - } else { - return *this; - } + return conjugate_function(*this).hold(); } ex symbol::real_part() const { - if (domain==domain::real || domain==domain::positive) - return *this; return real_part_function(*this).hold(); } ex symbol::imag_part() const { - if (domain==domain::real || domain==domain::positive) - return 0; return imag_part_function(*this).hold(); } diff --git a/ginac/symbol.h b/ginac/symbol.h index 42c6ae32..bd894c94 100644 --- a/ginac/symbol.h +++ b/ginac/symbol.h @@ -37,15 +37,10 @@ class symbol : public basic { GINAC_DECLARE_REGISTERED_CLASS(symbol, basic) - friend class realsymbol; - friend class possymbol; - -// member functions - // other constructors public: - explicit symbol(const std::string & initname, unsigned domain = domain::complex); - symbol(const std::string & initname, const std::string & texname, unsigned domain = domain::complex); + explicit symbol(const std::string & initname); + symbol(const std::string & initname, const std::string & texname); // functions overriding virtual functions from base classes public: @@ -70,7 +65,7 @@ protected: public: void set_name(const std::string & n) { name = n; } std::string get_name() const { return name; } - unsigned get_domain() const { return domain; } + virtual unsigned get_domain() const { return domain::complex; } protected: void do_print(const print_context & c, unsigned level) const; void do_print_latex(const print_latex & c, unsigned level) const; @@ -83,7 +78,6 @@ protected: unsigned serial; ///< unique serial number for comparison std::string name; ///< printname of this symbol std::string TeX_name; ///< LaTeX name of this symbol - unsigned domain; ///< domain of symbol, complex (default) or real private: static unsigned next_serial; }; @@ -92,44 +86,33 @@ private: /** Specialization of symbol to real domain */ class realsymbol : public symbol { - // constructors public: realsymbol(); - explicit realsymbol(const std::string & initname, unsigned domain = domain::real); - realsymbol(const std::string & initname, const std::string & texname, unsigned domain = domain::real); + explicit realsymbol(const std::string & initname); + realsymbol(const std::string & initname, const std::string & texname); + + unsigned get_domain() const { return domain::real; } + + ex conjugate() const { return *this; } + ex real_part() const { return *this; } + ex imag_part() const { return 0; } + + realsymbol* duplicate() const { return new realsymbol(*this); } }; /** Specialization of symbol to real domain */ -class possymbol : public symbol +class possymbol : public realsymbol { - // constructors public: possymbol(); - explicit possymbol(const std::string & initname, unsigned domain = domain::positive); - possymbol(const std::string & initname, const std::string & texname, unsigned domain = domain::positive); -}; - + explicit possymbol(const std::string & initname); + possymbol(const std::string & initname, const std::string & texname); -// utility functions + unsigned get_domain() const { return domain::positive; } -/** Specialization of is_exactly_a(obj) for realsymbol objects. */ -template<> inline bool is_exactly_a(const basic & obj) -{ - if (!is_a(obj)) - return false; - unsigned domain = static_cast(obj).get_domain(); - return domain==domain::real || domain==domain::positive; -} - -/** Specialization of is_exactly_a(obj) for possymbol objects. */ -template<> inline bool is_exactly_a(const basic & obj) -{ - if (!is_a(obj)) - return false; - unsigned domain = static_cast(obj).get_domain(); - return domain == domain::positive; -} + possymbol* duplicate() const { return new possymbol(*this); } +}; } // namespace GiNaC diff --git a/ginsh/ginsh.h b/ginsh/ginsh.h index a4159b67..9d8ef85a 100644 --- a/ginsh/ginsh.h +++ b/ginsh/ginsh.h @@ -66,7 +66,7 @@ extern int num_files; extern char **file_list; // Table of all used symbols -typedef map sym_tab; +typedef map sym_tab; extern sym_tab syms; // Type of symbols to generate (real or complex) diff --git a/ginsh/ginsh_lexer.ll b/ginsh/ginsh_lexer.ll index 817df6ec..cdb4237b 100644 --- a/ginsh/ginsh_lexer.ll +++ b/ginsh/ginsh_lexer.ll @@ -113,9 +113,13 @@ real_symbols return T_REAL_SYMBOLS; sym_tab::const_iterator i = syms.find(yytext); if (i == syms.end()) { if (symboltype == domain::complex) { - yylval = syms[yytext] = *(new symbol(yytext)); + symbol tmp(yytext); + syms[yytext] = tmp; + yylval = tmp; } else { - yylval = syms[yytext] = *(new symbol(yytext, domain::real)); + realsymbol tmp(yytext); + syms[yytext] = tmp; + yylval = tmp; } } else yylval = i->second; -- 2.44.0