/*============================================================================= vim: spell spelllang=en textwidth=79 This file is part of FLINT. FLINT 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. FLINT 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 FLINT; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2013 Tom Bachmann ******************************************************************************/ ******************************************************************************* Rules and standard methods A typical expression template class begins with the following lines of code: \begin{lstlisting}[language=c++] template class some_expression : public expression, Operation, Data> { // ... }; \end{lstlisting} We document here methods this class inherits from its base, and how they relate to rules. There are the following public typedefs: \begin{description} \item[ev\_traits\_t] A specialisation of \code{detail::evaluation_traits}. Used to compute the rule for evaluation. \item[derived\_t] The specialised derived class. \item[evaluated\_t] The resulting type of evaluating this expression. \item[evaluation\_return\_t] The return type of \code{evaluate()}. This differs from the above for immediates, where evaluation returns a reference instead of a copy. \item[data\_t] The same as \code{Data}. \item[operation\_t] The same as \code{Operation}. \end{description} ******************************************************************************* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Standard methods +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ data_t& some_expression::_data() const data_t& some_expression::_data() const Obtain the data related to this expression template. evaluated_t some_expression::create_temporary() const Default instantiate a temporary. Override this if your class is not default instantiable. template T some_expression::to() const Convert self to type \code{T} (after evaluating). Uses \code{rules::conversion}. void some_expression::print(std::ostream& o) const Print self to \code{o}. Uses \code{rules::print} or \code{rules::to_string}. int some_expression::print(FILE* f = stdout) const Print self to \code{f}. Uses \code{rules::cprint}. int some_expression::print_pretty(FILE* f = stdout) const Print self to \code{f}. Uses \code{rules::print_pretty}. template int some_expression::print_pretty(const T& extra, FILE* f = stdout) const Print self to \code{f}. Uses \code{rules::print_pretty} with two arguments. int some_expression::read(FILE* f = stdin) Read self from \code{f}. Uses \code{rules::read}. const evaluation_return_t some_expression::evaluate() const Evaluate self. template void some_expression::set(const T& t) Assign \code{t} to self. Uses evaluation and/or \code{rules::assignment}. template bool some_expression::equals(const T& t) const Determine if \code{t} is equal to self. Uses \code{rules::equals} or \code{rules::cmp}. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Global functions In addition to member functions, flintxx also provides a number of global functions. In general these operate on sets of arguments at least one of which derives from \code{expression}, and are conditionally enabled only if the relevant operation is implemented (via a rule). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ template std::ostream& operator<<(std::ostream& o, const Expr& e) Print \code{e} to \code{o}. Uses the member \code{print}. template bool operator==(const Expr1&, const Expr2&) template bool operator!=(const Expr1&, const Expr2&) Compare two expressions. Uses the member \code{equals}. template bool operator??(const Expr1&, const Expr2&) Relational operators \code{< > <= =>} are implemented using \code{rules::cmp}. template ?? operator??(const Expr1&, const Expr2&) Arithmetic operators \code{+ - * / % & | ^ << >>} are implemented by constructing new expression templates with operation \code{operations::plus} etc. template ?? operator??(const Expr1&) Unary operators \code{- ~} are implemented by constructing new expression templates with operation \code{operations::negate} and \code{operations::complement}. template ?? operator?=(const Expr1&, const Expr2&) Arithmetic-assignment operators \code{+= -= *= /= %= |= &= ^=}. template int print(const Expr1&) template int print(FILE*f, const Expr1&) template int print_pretty(const Expr1&) template int print_pretty(FILE*f, const Expr1&) template int print_pretty(const Expr1&, const T& extra) template int print_pretty(FILE*f, const Expr1&, const T& extra) Forward to member. template void swap(Expr1& e1, Expr2& e2) Swap \code{e1} and \code{e2} using \code{rules::swap}. Note that via ADL, this can be used by STL containers. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx classes The flint wrapper classes share some other common interfaces. These have to be enabled using the convenience macros in \code{flintxx/flint_classes.h} (q.v.). Here \code{accessname} and \code{ctype} are specified via the macros. For e.g. \code{fmpz_polyxx} these are \code{_poly} and \code{fmpz_poly_struct}. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ?? some_expression::accessname() ?? some_expression::accessname() const Obtain a reference to the underlying C struct. This is only available on immediate expressions. some_expression_ref::some_expression_ref(some_expression&) some_expression_srcref::some_expression_srcref(const some_expression&) some_expression_srcref::some_expression_srcref(some_expression_ref) Build a reference type. Note that these are \emph{implicit} constructors. static some_expression_ref some_expression_ref::make(ctype*) static some_expression_srcref some_expression_srcref::make(const ctype*) Build a reference type from a pointer to the underlying C struct. ******************************************************************************* Convenience macros ******************************************************************************* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx/rules.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FLINT_DEFINE_GET2(name, totype, fromtype1, fromtype2, eval) Specialise a getter called \code{name}, which takes arguments \code{e1} of type \code{fromtype1} and \code{e2} of type \code{fromtype2}. It returns \code{totype} by executing \code{eval}. FLINT_DEFINE_GET(name, totype, fromtype, eval) Same as \code{FLINT_DEFINE_GET2(name, totype, fromtype, fromtype, eval)}. FLINT_DEFINE_GET_COND(name, totye, cond, eval) Specialise a getter called \code{name}, which takes an argument \code{from} of type \code{T:cond} It returns \code{totype} by executing \code{eval}. FLINT_DEFINE_DOIT(name, totype, fromtype, eval) Specialise a doit rule called \code{name}, which takes arguments \code{to} of type \code{totype&} and \code{from} of type \code{const fromtype&}, and executes \code{eval}. FLINT_DEFINE_DOIT_COND(name, totype, cond, eval) Same as above, but takes \code{const T& from} for any \code{T:cond}. FLINT_DEFINE_DOIT_COND2(name, cond1, cond2, eval) Same as \code{FLINT_DEFINE_DOIT_COND}, but takes \code{T& to} and \code{const U& from} for any \code{T} satisfying \code{cond1} and \code{U} satisfying \code{cond2}. FLINT_DEFINE_PRINT_COND(cond, eval) Specialise the \code{cprint} rule. This takes a arguments \code{FILE* to} and \code{const T& from} for any \code{T:cond}. It prints \code{from} to \code{to} and returns \code{int} by executing \code{eval}. FLINT_DEFINE_PRINT_PRETTY_COND(cond, eval) Same as above, but with \code{print_pretty} instead of \code{cprint}. FLINT_DEFINE_PRINT_PRETTY_COND2(cond, extratype, eval) Same as above, but takes an additional argument \code{extratype extra}. Useful e.g. when printing polynomials and taking an extra variable name. FLINT_DEFINE_READ_COND(cond, eval) Specialise the \code{read} rule. This takes a arguments \code{FILE* from} and \code{T& to} for any \code{T:cond}. It reads \code{to} from \code{from} and returns \code{int} by executing \code{eval}. FLINT_DEFINE_UNARY_EXPR_(name, rtype, type, eval) Specialise the unary expression rule for \code{operations::name} with nominal return type \code{rtype}. It takes arguments \code{V& to} and \code{const type& from}. Here \code{V} is any type which \code{rtype} can be evaluated into. Executes \code{eval}. FLINT_DEFINE_UNARY_EXPR(name, type, eval) Same as \code{FLINT_DEFINE_UNARY_EXPR_(name, type, type, eval)}. FLINT_DEFINE_BINARY_EXPR2(name, rtype, type1, type2, eval) Specialise the binary expression rule for \code{operations::name} of nominal return type \code{rtype}, and arguments \code{type1} and \code{type2}. FLINT_DEFINE_BINARY_EXPR(name, type, eval) Same as \code{FLINT_DEFINE_BINARY_EXPR2(name, type, type, type, eval)}. FLINT_DEFINE_CBINARY_EXPR(name, type, eval) Same as above, but with \code{commutative_binary_expression} instead of \code{binary_expression}. FLINT_DEFINE_BINARY_EXPR_COND(name, type, cond, eval) FLINT_DEFINE_CBINARY_EXPR_COND(name, type, cond, eval) Specialise the (commutative) binary expression rule for \code{operations::name} of nominal return type \code{type}, and arguments \code{type} and \code{T:cond}. FLINT_DEFINE_BINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) FLINT_DEFINE_CBINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) Specialise the (commutative) binary expression rule for \code{operations::name} of nominal return type \code{rettype}, and arguments \code{T:cond1} and \code{U:cond2}. FLINT_DEFINE_THREEARY_EXPR_COND3(name, rettype, cond1, cond2, cond3, eval) FLINT_DEFINE_FOURARY_EXPR_COND4(name, retttype, cond1 ... cond4, eval) FLINT_DEFINE_FIVEARY_EXPR_COND5(name, rettype, cond1 ... cond5, eval) FLINT_DEFINE_SIXARY_EXPR_COND6(name, rettype, cond1 ... cond6, eval) FLINT_DEFINE_SEVENARY_EXPR_COND7(name, rettype, cond1 ... cond7, eval) Specialise higher order rules, similarly to the above. FLINT_DEFINE_THREEARY_EXPR(name, retttype, T1, T2, T3, eval) Specialise a threeary expression rule unconditionally. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx/expression.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FLINT_DEFINE_UNNOP(name) FLINT_DEFINE_BINOP(name) FLINT_DEFINE_THREEARY(name) FLINT_DEFINE_FOURARY(name) FLINT_DEFINE_FIVEARY(name) FLINT_DEFINE_SIXARY(name) FLINT_DEFINE_SEVENARY(name) Introduce a new n-ary operation \code{operations::##name##_op} and make it available. This has to be called in namespace \code{flint}. FLINT_DEFINE_UNNOP_HERE(name) FLINT_DEFINE_BINOP_HERE(name) FLINT_DEFINE_THREEARY_HERE(name) FLINT_DEFINE_FOURARY_HERE(name) FLINT_DEFINE_FIVEARY_HERE(name) FLINT_DEFINE_SIXARY_HERE(name) FLINT_DEFINE_SEVENARY_HERE(name) Make the n-ary operation \code{operations::##name##_op} available in the current namespace. FLINT_DEFINE_THREEARY_HERE_2DEFAULT(name, type1, val1, type2, val2) Make the threeary operation \code{name} available in current namespace, but with only two arguments, the second of which is of type \code{type1} and defaults to \code{val1}, and the third argument always (implicitly) of type \code{type2} and value \code{val2}. The suggested usage of this macro is to first call \code{FLINT_DEFINE_THREEARY_HERE} (or \code{FLINT_DEFINE_THREEARY}), and then call \code{FLINT_DEFINE_THREEARY_HERE_2DEFAULT}. The effect will be an operation which can be invoked with 1, 2 or 3 arguments. FLINT_UNOP_ENABLE_RETTYPE(name, T1) FLINT_BINOP_ENABLE_RETTYPE(name, T1, T2) FLINT_THREEARY_ENABLE_RETTYPE(name, T1, T2, T3) FLINT_FOURARY_ENABLE_RETTYPE(name, T1, T2, T3, T4) FLINT_FIVEARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5) FLINT_SIXARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5, T6) FLINT_SEVENARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5, T6, T7) Obtain the resulting type of invoking \code{name} with arguments of types \code{T1}, ..., \code{Tn} if this is possible. Otherwise results in an (SFINAE) error. FLINT_UNOP_BUILD_RETTYPE(name, rettype, T) Obtain the resulting type (i.e. expression template) of invoking \code{name} with argument type \code{T}, assuming the nominal return type is \code{rettype}. This version is sometimes necessary to break cyclic dependencies. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx/flint\_classes.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FLINTXX_DEFINE_BASICS(name) Add standard constructors (forwarded to \code{data_t}, and implicit ones for reference types). Here \code{name} is the name of the expression template class. FLINTXX_DEFINE_C_REF(name, ctype, accessname) Enable the reference types scheme. FLINTXX_DEFINE_FORWARD_STATIC(funcname) Add a statically forwarded constructor (similar to \code{make} for reference types) which invokes a static constructor of the same name of \code{data_t}. FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(rettype, name) Add a no-argument member function which applies self to the lazy function \code{name}, where \code{name} has nominal return type \code{rettype}. (The return type has to be specified to break circular dependencies.) FLINTXX_DEFINE_MEMBER_UNOP(name) Same as above, but where the nominal return type is the (evaluated type of the) current expression template class. FLINTXX_DEFINE_MEMBER_BINOP(name) FLINTXX_DEFINE_MEMBER_3OP(name) FLINTXX_DEFINE_MEMBER_4OP(name) FLINTXX_DEFINE_MEMBER_5OP(name) Add a member function which \code{n-1} arguments, the result of which is to invoke \code{name} on self and the arguments (in that order). FLINTXX_COND_S(Base) FLINTXX_COND_T(Base) Expands to a condition (which can be passed to e.g. \code{FLINT_DEFINE_CBINARY_EXPR_COND2}) appropriate for testing a source/target of type \code{Base}. FLINTXX_DEFINE_TO_STR(Base, eval) Add a \code{to_string} rule which works well with the \code{*_get_str} functions in FLINT. FLINTXX_DEFINE_SWAP(Base, eval) Add a swap rule. FLINTXX_DEFINE_CONVERSION_TMP(totype, Base, eval) Define a conversion rule from \code{Base} to \code{totype}, which default-constructs a temporary object \code{to} of type \code{totype}, then executes \code{eval}, and then returns \code{to}. FLINTXX_DEFINE_CMP(Base, eval) FLINTXX_DEFINE_EQUALS(Base, eval) Define a cmp/equality rule. FLINTXX_DEFINE_ASSIGN_STR(Base, eval) Define a string assignment rule (used by many polynomial classes). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx/matrix.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FLINTXX_DEFINE_MATRIX_METHODS(Traits) Inside a matrix expression template class definition, given the unified access traits \code{Traits} appropriate for this class, define the standard methods \code{rows, cols, create_temporary}. FLINTXX_DEFINE_TEMPORARY_RULES(Matrix) Given a matrix expression template class \code{Matrix}, define appropriate temporary instantiation rule, disable temporary merging, etc. ******************************************************************************* Helper functions ******************************************************************************* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flintxx/flint\_exception.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void execution_check(bool worked, const std::string& where, const std::string& context) If \code{worked} is true, do nothing. Else raise a \code{flint_exception} with message \code{context + " computation failed: " + where}. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ permxx.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ slong* maybe_perm_data(permxx* p) Return \code{0} if \code{p == 0}, and else the underlying data. It is helpful to use this together with \code{traits::is_maybe_perm} as condition.