X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fbasic.h;h=1af6f85844ca68683f2eb3a0111d6fcf02578a20;hb=d38e670373b3df4e7ff5835ac4f67743f1351e95;hp=24518464c93f3dad820d3fdcb1544ce599a7e0a5;hpb=c28e61da33905ddc69abf893aaffec98aa30d053;p=ginac.git diff --git a/ginac/basic.h b/ginac/basic.h index 24518464..1af6f858 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -3,7 +3,7 @@ * Interface to GiNaC's ABC. */ /* - * GiNaC Copyright (C) 1999-2010 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2016 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,18 +28,17 @@ #include "assertion.h" #include "registrar.h" -// CINT needs to work properly with -#include #include // for size_t #include #include #include // for typeid #include +#include namespace GiNaC { class ex; -class ex_is_less; +struct ex_is_less; class symbol; class numeric; class relational; @@ -93,7 +92,8 @@ struct map_function { /** Degenerate base class for visitors. basic and derivative classes * support Robert C. Martin's Acyclic Visitor pattern (cf. - * http://objectmentor.com/publications/acv.pdf). */ + * http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf + * or chapter 10 of Andrei Alexandrescu's "Modern C++ Design"). */ class visitor { protected: virtual ~visitor() {} @@ -128,11 +128,16 @@ public: // only const functions please (may break reference counting) /** Create a clone of this object on the heap. One can think of this as * simulating a virtual copy constructor which is needed for instance by * the refcounted construction of an ex from a basic. */ - virtual basic * duplicate() const { return new basic(*this); } + virtual basic * duplicate() const + { + basic * bp = new basic(*this); + bp->setflag(status_flags::dynallocated); + return bp; + } // evaluation - virtual ex eval(int level = 0) const; - virtual ex evalf(int level = 0) const; + virtual ex eval() const; + virtual ex evalf() const; virtual ex evalm() const; virtual ex eval_integ() const; protected: @@ -195,7 +200,7 @@ public: virtual ex series(const relational & r, int order, unsigned options = 0) const; // rational functions - virtual ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const; + virtual ex normal(exmap & repl, exmap & rev_lookup) const; virtual ex to_rational(exmap & repl) const; virtual ex to_polynomial(exmap & repl) const; @@ -298,11 +303,8 @@ protected: mutable unsigned hashvalue; ///< hash value }; - // global variables -extern int max_recursion_level; - // convenience type checker template functions @@ -310,7 +312,7 @@ extern int max_recursion_level; template inline bool is_a(const basic &obj) { - return dynamic_cast(&obj) != 0; + return dynamic_cast(&obj) != nullptr; } /** Check if obj is a T, not including base classes. */ @@ -320,6 +322,31 @@ inline bool is_exactly_a(const basic & obj) return typeid(T) == typeid(obj); } +/** Constructs a new (class basic or derived) B object on the heap. + * + * This function picks the object's ctor based on the given argument types. + * + * This helps the constructor of ex from basic (or a derived class B) because + * then the constructor doesn't have to duplicate the object onto the heap. + * See ex::construct_from_basic(const basic &) for more information. + */ +template +inline B & dynallocate(Args &&... args) +{ + return const_cast(static_cast((new B(std::forward(args)...))->setflag(status_flags::dynallocated))); +} +/** Constructs a new (class basic or derived) B object on the heap. + * + * This function is needed for GiNaC classes which have public ctors from + * initializer lists of expressions (which are not a type and not captured + * by the variadic template version). + */ +template +inline B & dynallocate(std::initializer_list il) +{ + return const_cast(static_cast((new B(il))->setflag(status_flags::dynallocated))); +} + } // namespace GiNaC #endif // ndef GINAC_BASIC_H