/usr/include/ginac/print.h is in libginac-dev 1.7.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | /** @file print.h
*
* Definition of helper classes for expression output. */
/*
* GiNaC Copyright (C) 1999-2017 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GINAC_PRINT_H
#define GINAC_PRINT_H
#include "class_info.h"
#include <iosfwd>
#include <memory>
#include <string>
namespace GiNaC {
/** This class stores information about a registered print_context class. */
class print_context_options {
public:
print_context_options(const char *n, const char *p, unsigned i)
: name(n), parent_name(p), id(i) {}
const char *get_name() const { return name; }
const char *get_parent_name() const { return parent_name; }
unsigned get_id() const { return id; }
private:
const char *name; /**< Class name. */
const char *parent_name; /**< Name of superclass. */
unsigned id; /**< ID number (assigned automatically). */
};
typedef class_info<print_context_options> print_context_class_info;
/** Flags to control the behavior of a print_context. */
class print_options {
public:
enum {
print_index_dimensions = 0x0001 ///< print the dimensions of indices
};
};
/** Common part of GINAC_DECLARE_PRINT_CONTEXT_BASE and GINAC_DECLARE_PRINT_CONTEXT_DERIVED. */
#define GINAC_DECLARE_PRINT_CONTEXT_COMMON(classname) \
public: \
friend class function_options; \
friend class registered_class_options; \
static const GiNaC::print_context_class_info &get_class_info_static(); \
classname();
#define GINAC_DECLARE_PRINT_CONTEXT_BASE(classname) \
GINAC_DECLARE_PRINT_CONTEXT_COMMON(classname) \
virtual const GiNaC::print_context_class_info &get_class_info() const { return classname::get_class_info_static(); } \
virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \
virtual classname * duplicate() const { return new classname(*this); } \
private:
/** Macro for inclusion in the declaration of a print_context class.
* It declares some functions that are common to all classes derived
* from 'print_context' as well as all required stuff for the GiNaC
* registry. */
#define GINAC_DECLARE_PRINT_CONTEXT(classname, supername) \
GINAC_DECLARE_PRINT_CONTEXT_COMMON(classname) \
typedef supername inherited; \
const GiNaC::print_context_class_info &get_class_info() const override { return classname::get_class_info_static(); } \
const char *class_name() const override { return classname::get_class_info_static().options.get_name(); } \
classname * duplicate() const override { return new classname(*this); } \
private:
/** Macro for inclusion in the implementation of each print_context class. */
#define GINAC_IMPLEMENT_PRINT_CONTEXT(classname, supername) \
const GiNaC::print_context_class_info &classname::get_class_info_static() \
{ \
static GiNaC::print_context_class_info reg_info = GiNaC::print_context_class_info(GiNaC::print_context_options(#classname, #supername, GiNaC::next_print_context_id++)); \
return reg_info; \
}
extern unsigned next_print_context_id;
/** Base class for print_contexts. */
class print_context
{
GINAC_DECLARE_PRINT_CONTEXT_BASE(print_context)
public:
print_context(std::ostream &, unsigned options = 0);
virtual ~print_context() {}
std::ostream & s; /**< stream to output to */
unsigned options; /**< option flags */
};
/** Context for default (ginsh-parsable) output. */
class print_dflt : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_dflt, print_context)
public:
print_dflt(std::ostream &, unsigned options = 0);
};
/** Context for latex-parsable output. */
class print_latex : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_latex, print_context)
public:
print_latex(std::ostream &, unsigned options = 0);
};
/** Context for python pretty-print output. */
class print_python : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_python, print_context)
public:
print_python(std::ostream &, unsigned options = 0);
};
/** Context for python-parsable output. */
class print_python_repr : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_python_repr, print_context)
public:
print_python_repr(std::ostream &, unsigned options = 0);
};
/** Context for tree-like output for debugging. */
class print_tree : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_tree, print_context)
public:
print_tree(unsigned d);
print_tree(std::ostream &, unsigned options = 0, unsigned d = 4);
const unsigned delta_indent; /**< size of indentation step */
};
/** Base context for C source output. */
class print_csrc : public print_context
{
GINAC_DECLARE_PRINT_CONTEXT(print_csrc, print_context)
public:
print_csrc(std::ostream &, unsigned options = 0);
};
/** Context for C source output using float precision. */
class print_csrc_float : public print_csrc
{
GINAC_DECLARE_PRINT_CONTEXT(print_csrc_float, print_csrc)
public:
print_csrc_float(std::ostream &, unsigned options = 0);
};
/** Context for C source output using double precision. */
class print_csrc_double : public print_csrc
{
GINAC_DECLARE_PRINT_CONTEXT(print_csrc_double, print_csrc)
public:
print_csrc_double(std::ostream &, unsigned options = 0);
};
/** Context for C source output using CLN numbers. */
class print_csrc_cl_N : public print_csrc
{
GINAC_DECLARE_PRINT_CONTEXT(print_csrc_cl_N, print_csrc)
public:
print_csrc_cl_N(std::ostream &, unsigned options = 0);
};
/** Check if obj is a T, including base classes. */
template <class T>
inline bool is_a(const print_context & obj)
{ return dynamic_cast<const T *>(&obj) != nullptr; }
class basic;
/** Base class for print_functor handlers */
class print_functor_impl {
public:
virtual ~print_functor_impl() {}
virtual print_functor_impl *duplicate() const = 0;
virtual void operator()(const basic & obj, const print_context & c, unsigned level) const = 0;
};
/** print_functor handler for pointer-to-functions of class T, context type C */
template <class T, class C>
class print_ptrfun_handler : public print_functor_impl {
public:
typedef void (*F)(const T &, const C &, unsigned);
print_ptrfun_handler(F f_) : f(f_) {}
print_ptrfun_handler *duplicate() const override { return new print_ptrfun_handler(*this); }
void operator()(const basic & obj, const print_context & c, unsigned level) const override
{
// Call the supplied function
f(dynamic_cast<const T &>(obj), dynamic_cast<const C &>(c), level);
}
private:
F f;
};
/** print_functor handler for member functions of class T, context type C */
template <class T, class C>
class print_memfun_handler : public print_functor_impl {
public:
typedef void (T::*F)(const C & c, unsigned level) const;
print_memfun_handler(F f_) : f(f_) {}
print_memfun_handler *duplicate() const override { return new print_memfun_handler(*this); }
void operator()(const basic & obj, const print_context & c, unsigned level) const override
{
// Call the supplied member function
return (dynamic_cast<const T &>(obj).*f)(dynamic_cast<const C &>(c), level);
}
private:
F f;
};
/** This class represents a print method for a certain algebraic class and
* print_context type. Its main purpose is to hide the difference between
* member functions and nonmember functions behind one unified operator()
* interface. print_functor has value semantics and acts as a smart pointer
* (with deep copy) to a class derived from print_functor_impl which
* implements the actual function call. */
class print_functor {
public:
print_functor() : impl(nullptr) {}
print_functor(const print_functor & other) : impl(other.impl.get() ? other.impl->duplicate() : 0) {}
print_functor(std::unique_ptr<print_functor_impl> impl_) : impl(std::move(impl_)) {}
template <class T, class C>
print_functor(void f(const T &, const C &, unsigned)) : impl(new print_ptrfun_handler<T, C>(f)) {}
template <class T, class C>
print_functor(void (T::*f)(const C &, unsigned) const) : impl(new print_memfun_handler<T, C>(f)) {}
print_functor & operator=(const print_functor & other)
{
if (this != &other) {
print_functor_impl *p = other.impl.get();
impl.reset(p ? other.impl->duplicate() : nullptr);
}
return *this;
}
void operator()(const basic & obj, const print_context & c, unsigned level) const
{
(*impl)(obj, c, level);
}
bool is_valid() const { return impl.get(); }
private:
std::unique_ptr<print_functor_impl> impl;
};
} // namespace GiNaC
#endif // ndef GINAC_BASIC_H
|