source: git/kernel/old/old.Poly.h @ 0a4a20d

spielwiese
Last change on this file since 0a4a20d was 0a4a20d, checked in by Hans Schoenemann <hannes@…>, 18 months ago
Merge pull request #1159 from fchapoton/codespell_linter trying to add a codespell linter for kernel/
  • Property mode set to 100644
File size: 14.0 KB
RevLine 
[90be05]1
[3c7942]2
3
4#ifndef POLYCPP_HEADER
5#define POLYCPP_HEADER
[599326]6#include <kernel/mod2.h>
7#include <kernel/IIntvec.h>
[210e07]8#include <coeffs/numbers.h>
[599326]9#include <kernel/Number.h>
[737a68]10#include <kernel/polys.h>
[210e07]11#include <polys/monomials/ring.h>
[90be05]12
13
[3c7942]14#include <boost/shared_ptr.hpp>
[90be05]15
16#include <vector>
[e604cd]17#include <exception>
18using std::exception;
[90be05]19
[3c7942]20#define BOOST_DISABLE_THREADS
[90be05]21
[e604cd]22class DifferentDomainException: public exception{
23
24};
25class ExceptionBasedErrorHandler{
26    public:
27        static const bool handleErrors=true;
28        static void handleDifferentRing(ring r, ring s){
29        PrintS("throwing");
30        throw DifferentDomainException();
31    }
32};
[90be05]33
[3c7942]34//PolyImpl is a 08/15 poly wrapper
35//Poly wraps around PolyImpl with reference counting using boost
[8457864]36class TrivialErrorHandler{
37    public:
[e604cd]38    static const bool handleErrors=false;
39    static void handleDifferentRing(ring r, ring s){
[8457864]40    }
41};
[7f4d50]42typedef TrivialErrorHandler MyErrorHandler;
[3c7942]43class PolyImpl{
[8457864]44  template <poly_variant,class,class> friend class PolyBase;
45  //friend class PolyBase<POLY_VARIANT_RING,Poly,TrivialErrorHandler>;
46  //friend class PolyBase<POLY_VARIANT_MODUL,Vector, TrivialErrorHandler>;
[c1e4cd]47  //friend class PolyBase<POLY_VARIANT_MODUL>;
[4e2486]48  friend class Poly;
[82f499]49  friend class Vector;
[f28d81]50  //friend class Number;
51 protected:
52  poly getInternalReference() const{
53    return p;
54  }
[3c7942]55 public:
56  ring getRing() const{
[7f4d50]57    return r.get();
[3c7942]58  }
[d964f9]59  friend inline bool operator==(const Poly& p1, const Poly& p2);
[451a9a]60  friend inline bool operator==(const Vector& p1, const Vector& p2);
[3c7942]61  friend PolyImpl operator+(const PolyImpl& p1, const PolyImpl& n2);
62  friend PolyImpl operator-(const PolyImpl& p1, const PolyImpl& n2);
63  friend PolyImpl operator/(const PolyImpl& p1, const PolyImpl& n2);
64  friend PolyImpl operator*(const PolyImpl& p1, const PolyImpl& n2);
65  friend bool operator==(const PolyImpl& p1, const PolyImpl& n2);
66  friend PolyImpl operator+(const PolyImpl& p1, int n2);
67  friend PolyImpl operator-(const PolyImpl& p1, int n2);
68  friend PolyImpl operator/(const PolyImpl& p1, int n2);
69  friend PolyImpl operator*(const PolyImpl& p1, int n2);
70  friend bool operator==(const PolyImpl& p1, int n2);
[a9c606]71  Number leadCoef(){
[7f4d50]72    return Number(p->coef,r.get());
[a9c606]73  }
[3c7942]74  PolyImpl& operator=(const PolyImpl& p2){
[53bb34c]75    //durch Reihenfolge Selbstzuweisungen beruecksichtigt
[3c7942]76    if (this==&p2) return *this;
[7f4d50]77    poly pc=p_Copy(p2.p,p2.r.get());
[a171c0]78    if(r!=NULL)
[7f4d50]79      p_Delete(&p,r.get());
[3c7942]80    r=p2.r;
81    p=pc;
82    return *this;
83  }
84  PolyImpl operator-(){
85    PolyImpl t(*this);
[7f4d50]86    t.p=p_Copy(p,r.get());
87    t.p=p_Neg(t.p,r.get());
[3c7942]88    return t;
89  }
90  PolyImpl& operator+=(const PolyImpl & p2){
91    if (r!=p2.r){
[7b9b8e5]92      WerrorS("not the same ring");
[3c7942]93      return *this;
94    }
95    if (this==&p2){
[7f4d50]96      number two=n_Init(2,r.get());
97      p_Mult_nn(p,two,r.get());
[3c7942]98      return *this;
99    }
[7f4d50]100    p=p_Add_q(p,p_Copy(p2.p,p2.r.get()),r.get());
[a9c298]101
[3c7942]102    return *this;
103  }
104  PolyImpl& operator*=(const PolyImpl & p2){
105    if (r!=p2.r){
[7b9b8e5]106      WerrorS("not the same ring");
[3c7942]107      return *this;
108    }
109    if (this==&p2){
[7f4d50]110      poly pc=p_Copy(p,r.get());
111      p=p_Mult_q(p,p2.p,r.get());
[3c7942]112      return *this;
113    }
[7f4d50]114    p=p_Mult_q(p,p_Copy(p2.p,p2.r.get()),r.get());
[3c7942]115    return *this;
116  }
[f28d81]117  PolyImpl& operator*=(const Number & n){
118    if (r!=n.r){
[7b9b8e5]119      WerrorS("not the same ring");
[f28d81]120      return *this;
121    }
[a9c298]122
[7f4d50]123    p=p_Mult_nn(p,n.n,r.get());
[f28d81]124    return *this;
125  }
[3c7942]126  PolyImpl& operator-=(const PolyImpl & p2){
127    if (r!=p2.r){
[7b9b8e5]128      WerrorS("not the same ring");
[3c7942]129      return *this;
130    }
131    if (this==&p2){
[7f4d50]132      p_Delete(&p,r.get());
[3c7942]133      p=NULL;
134      return *this;
135    }
136
[7f4d50]137    poly pc=p_Copy(p2.p,p2.r.get());
138    pc=p_Neg(pc,r.get());
139    p=p_Add_q(p,pc,r.get());
[3c7942]140
[a9c298]141
[3c7942]142    return *this;
143  }
144
145
146  PolyImpl& operator=(int n){
[a9c298]147
[7f4d50]148    p_Delete(&p,r.get());
149    p=p_ISet(n,r.get());
[3c7942]150    return *this;
[a9c298]151
[3c7942]152  }
[a9c298]153
[3c7942]154
155  PolyImpl(){
156    r=currRing;
157    p=NULL;
158  }
159  PolyImpl(const PolyImpl & p){
160    r=p.r;
[7f4d50]161    this->p=p_Copy(p.p,r.get());
[3c7942]162  }
[7f4d50]163  PolyImpl(poly p, intrusive_ptr<ip_sring> r){
164    this->p=p_Copy(p,r.get());
[3c7942]165    this->r=r;
166  }
[7f4d50]167  PolyImpl(poly p, intrusive_ptr<ip_sring> r,int){
[90be05]168    this->p=p;
169    this->r=r;
170  }
[7f4d50]171  PolyImpl(int n, intrusive_ptr<ip_sring> r){
172    this->p=p_ISet(n,r.get());
[3c7942]173    this->r=r;
174  }
[49c9e43]175  PolyImpl(const Number & n){
[a9c298]176
[547474]177    r=n.r.get();
[7f4d50]178    this->p=p_NSet(n_Copy(n.n,r.get()),r.get());
[a9c298]179
[49c9e43]180  }
[3c7942]181  explicit PolyImpl(int n){
182    r=currRing;
[7f4d50]183    this->p=p_ISet(n,r.get());
[3c7942]184  }
185  void print(){
[7f4d50]186    p_Write(p,r.get(),r.get());
[3c7942]187  }
188
189  virtual ~PolyImpl(){
[a171c0]190    if (r!=NULL)
[7f4d50]191      p_Delete(&p,r.get());
[3c7942]192  }
193
194 protected:
195  poly p;
[7f4d50]196  intrusive_ptr<ip_sring> r;
[3c7942]197
198};
199
[c300eca]200inline PolyImpl operator+(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]201  PolyImpl erg(p1);
202  erg+=p2;
203  return erg;
204}
[c300eca]205inline PolyImpl operator*(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]206  PolyImpl erg(p1);
207  erg*=p2;
208  return erg;
209}
[c300eca]210inline PolyImpl operator-(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]211  PolyImpl erg(p1);
212  erg-=p2;
213  return erg;
214}
[547474]215
[3c7942]216
217
[c300eca]218inline PolyImpl operator+(const PolyImpl &p1, int p2){
[3c7942]219  PolyImpl erg(p1);
[7f4d50]220  erg+=PolyImpl(p2,p1.r.get());
[3c7942]221  return erg;
222}
[c300eca]223inline PolyImpl operator*(const PolyImpl &p1, int p2){
[3c7942]224  PolyImpl erg(p1);
[7f4d50]225  erg*=PolyImpl(p2,p1.r.get());
[3c7942]226  return erg;
227}
[c300eca]228inline PolyImpl operator-(const PolyImpl &p1, int p2){
[3c7942]229  PolyImpl erg(p1);
230  erg-=PolyImpl(p2,p1.r);
231  return erg;
232}
233
[547474]234
[c300eca]235inline PolyImpl operator+(int p1, const PolyImpl& p2){
[3c7942]236  PolyImpl erg(p2);
237  return erg+=PolyImpl(p1,p2.getRing());
238}
239
[c300eca]240inline PolyImpl operator*(int p1, const PolyImpl& p2){
[3c7942]241  PolyImpl erg(p2);
242  return erg*=PolyImpl(p1,p2.getRing());
243}
[547474]244
[3c7942]245using namespace boost;
246
[90be05]247
248template<class T> class ConstTermReference{
249 private:
250  ring r;
251  poly t;
252 public:
[ef1452]253  operator T() const {
[90be05]254    return T(p_Head(t,r),r);
255  }
256  ConstTermReference(poly p, ring r){
257    this->t=p;
258    this->r=r;
259  }
[a9c606]260  bool isConstant() const{
261    return p_LmIsConstant(t,r);
262  }
[a9c298]263
[90be05]264};
[6bfb0e]265
[90be05]266template<class T> class PolyInputIterator:
[e2eba5]267public std::iterator<std::input_iterator_tag,T,int, shared_ptr<const T>,ConstTermReference<T> >
[90be05]268{
269
[a9c298]270
[90be05]271 private:
272  poly t;
273  ring r;
274  public:
275  bool operator==(const PolyInputIterator& t2){
276    return t2.t==t;
277  }
278  bool operator!=(const PolyInputIterator& t2){
279    return t2.t!=t;
280  }
281  PolyInputIterator(poly p, ring r){
282    t=p;
283    this->r=r;
284  }
285  PolyInputIterator(const PolyInputIterator& it){
286    t=it.t;
287    r=it.r;
288  }
289  PolyInputIterator& operator++(){
290    t=t->next;
291    return *this;
292  }
293  PolyInputIterator operator++(int){
294    PolyInputIterator it(*this);
295    ++(*this);
296    return it;
297  }
298  const ConstTermReference<T> operator*(){
299    return ConstTermReference<T> (t,r);
300  }
[e2eba5]301  shared_ptr<const T> operator->(){
302    return shared_ptr<const T>(new T(p_Head(t,r),r,0));
[90be05]303  }
304
305};
[ecbe9f7]306
[8457864]307template<poly_variant variant, class create_type_input, class error_handle_traits> class PolyBase{
308 private:
309    typedef PolyBase<variant,create_type_input,error_handle_traits> ThisType;
[3c7942]310 public:
[244fa5]311  poly as_poly() const{
[7f4d50]312    return p_Copy(ptr->p,ptr->getRing());
[b6e761]313  }
[e604cd]314  template<class T> void checkIsSameRing(T& p){
315    if (error_handle_traits::handleErrors){
316                 if (p.getRing()!=this->getRing()){
317   error_handle_traits::handleDifferentRing(
318    this->getRing(),
319    p.getRing()
320   );
321        }
322    }
323  }
[c1e4cd]324  typedef create_type_input create_type;
325  typedef PolyInputIterator<create_type> iterator;
[5139d6]326  Intvec leadExp(){
327    int nvars=rVar(ptr->r);
328    Intvec res(nvars);
329    for(int i=0;i<nvars;i++){
[7f4d50]330      res[i]=p_GetExp(ptr->p,i+1,ptr->getRing());
[5139d6]331    }
332    return res;
[a9c298]333  }
[3c7942]334  void copy_on_write(){
335    if (!ptr.unique()){
336      ptr.reset(new PolyImpl(*ptr));
337    }
338  }
[e2eba5]339  void print() const {
[3c7942]340    ptr->print();
341  }
[c858487]342  //* resource managed by Singular
[52a99a7]343  char* c_string() const{
[3c7942]344
[7f4d50]345    return p_String(ptr->p,ptr->getRing(),ptr->getRing());
[f28d81]346  }
[3c7942]347
[ecbe9f7]348  PolyBase(ring r=currRing):ptr(new PolyImpl((poly) NULL,r)){
[3c7942]349  }
[6bfb0e]350
[ecbe9f7]351  PolyBase(const char* c, ring r=currRing):ptr(new PolyImpl((poly)NULL,r)){
[f28d81]352    //p_Read takes no const so do
353    char* cp=(char*) omalloc((strlen(c)+1)*sizeof(char));
354    strcpy(cp,c);
355    p_Read(cp,ptr->p,r);
356    omfree(cp);
[49c9e43]357  }
[ecbe9f7]358  PolyBase(const PolyBase&p):ptr(p.ptr){
[49c9e43]359  }
[c1e4cd]360
[6bfb0e]361
362
363  PolyBase& operator+=(const PolyBase& p2){
[e604cd]364    checkIsSameRing(p2);
[3c7942]365    copy_on_write();
[b4e3724]366    *ptr += *p2.ptr;
[a9c298]367
[b4e3724]368    return *this;
369  }
[fd283f]370  PolyBase& operator*=(const Poly & p2);
[ecbe9f7]371  PolyBase& operator*=(Number n){
[f28d81]372    copy_on_write();
373    *ptr *=n;
[a9c298]374
[f28d81]375    return *this;
376  }
[3c7942]377  /*  void print(){
378     StringSetS("");
379     write();
[00d2a4]380     { char* s = StringEndS(); PrintS(s); omFree(s); }
[3c7942]381     }*/
[ecbe9f7]382  virtual ~PolyBase(){}
[6bfb0e]383  PolyBase(poly p, ring r):ptr(new PolyImpl(p_Copy(p,r),r)){
[90be05]384  }
[ecbe9f7]385  PolyBase(poly p, ring r,int):ptr(new PolyImpl(p,r,0)){
[90be05]386  }
[e2eba5]387  /*Poly(Poly& p){
[90be05]388    ptr=p.ptr;
[e2eba5]389    }*/
[49c9e43]390
[c1e4cd]391  PolyInputIterator<create_type> begin(){
[7f4d50]392    return PolyInputIterator<create_type>(ptr->p,ptr->getRing());
[90be05]393  }
[c1e4cd]394  PolyInputIterator<create_type> end(){
[7f4d50]395    return PolyInputIterator<create_type>(NULL, ptr->getRing());
[90be05]396  }
[a9c606]397  ring getRing() const{
[f28d81]398    return ptr->getRing();
399  }
[9ec8a1]400  int lmTotalDegree() const{
401    return pTotaldegree(ptr->p);
402  }
[a9c606]403  Number leadCoef(){
404    return ptr->leadCoef();
405  }
[3ece2b]406  create_type operator-(){
407    create_type erg(*this);
[7f4d50]408    erg*=Number(-1,ptr->getRing());
[3ece2b]409    return erg;
410  }
[3c7942]411 protected:
[a9c298]412
[ecbe9f7]413  PolyBase(PolyImpl& impl):ptr(&impl){
[a9c298]414
[3c7942]415  }
[f28d81]416  poly getInternalReference(){
417    return ptr->getInternalReference();
418  }
[6bfb0e]419 protected:
[9ec8a1]420
[3c7942]421  shared_ptr<PolyImpl> ptr;
[547474]422
[3c7942]423};
[6bfb0e]424
[7f4d50]425class Poly: public PolyBase<POLY_VARIANT_RING, Poly, MyErrorHandler>{
[8457864]426 private:
[7f4d50]427    typedef PolyBase<POLY_VARIANT_RING, Poly,MyErrorHandler> Base;
[9ec8a1]428  friend class Vector;
[7f4d50]429  friend class PolyBase<POLY_VARIANT_MODUL,Vector,MyErrorHandler>;
[6bfb0e]430 public:
[c1e4cd]431
[8457864]432  Poly(ring r=currRing):Base ((poly)NULL,r,0){
[6bfb0e]433  }
[8457864]434  Poly(int n, ring r=currRing):Base(*(new PolyImpl(n,r))){
[a9c298]435
[6bfb0e]436  }
[8457864]437  Poly(const char* c, ring r=currRing):Base(c,r){
[6bfb0e]438
439  }
[8457864]440  Poly(const Base& p):Base(p){
[6bfb0e]441  }
[a9c298]442
[8457864]443  Poly(const Number& n):Base(*(new PolyImpl(n))){
[a9c298]444
[4e2486]445  }
[8457864]446  Poly(poly p, ring r):Base(p,r){
[a9c298]447
[4e2486]448  }
[8457864]449  Poly(poly p, ring r, int):Base(p,r,0){
[6bfb0e]450  }
[8457864]451  Poly(const std::vector<int>& v, ring r=currRing):Base(*(new PolyImpl((poly) NULL,r))){
[6bfb0e]452    unsigned int i;
453    int s=v.size();
454    poly p=p_ISet(1,r);
455    for(i=0;i<v.size();i++){
456      pSetExp(p,i+1,v[i]);
457    }
458    pSetm(p);
459    ptr.reset(new PolyImpl(p,r));
460  }
461  /*  Poly& operator+=(const Number& n){
462  Poly p2(n);
[c1e4cd]463  ((PolyBase<POLY_VARIANT_RING, Poly>&) (*this))+=p2;
[6bfb0e]464  return *this;
465  }*/
466  Poly& operator+=(const Poly& p ){
467
[8457864]468    ((Base&)*this)+=p;
[6bfb0e]469    return *this;
470  }
[8457864]471  Poly& operator+=(const Base& p ){
[6bfb0e]472
[8457864]473    ((Base&)*this)+=p;
[6bfb0e]474    return *this;
475  }
[d964f9]476  friend inline bool operator==(const Poly& p1, const Poly& p2);
[c1e4cd]477
[82f499]478};
[7f4d50]479class Vector: public PolyBase<POLY_VARIANT_MODUL, Vector, MyErrorHandler>{
[8457864]480 private:
[7f4d50]481    typedef PolyBase<POLY_VARIANT_MODUL, Vector, MyErrorHandler> Base;
[82f499]482 public:
483
[8457864]484  Vector(ring r=currRing):Base ((poly)NULL,r,0){
[82f499]485  }
[8457864]486  Vector(int n, ring r=currRing):Base(*(new PolyImpl(n,r))){
[a9c298]487
[82f499]488  }
[8457864]489  Vector(const char* c, ring r=currRing):Base(c,r){
[82f499]490
491  }
[8457864]492  Vector(const Base& p):Base(p){
[82f499]493  }
[a9c298]494
[9ec8a1]495
[8457864]496  Vector(poly p, ring r):Base(p,r){
[a9c298]497
[82f499]498  }
[8457864]499  Vector(poly p, ring r, int):Base(p,r,0){
[82f499]500  }
[8457864]501  Vector(std::vector<int> v, ring r=currRing):Base(*(new PolyImpl((poly) NULL,r))){
[82f499]502    unsigned int i;
503    int s=v.size();
504    poly p=p_ISet(1,r);
505    for(i=0;i<v.size();i++){
506      pSetExp(p,i+1,v[i]);
507    }
508    pSetm(p);
509    ptr.reset(new PolyImpl(p,r));
510  }
511  /*  Poly& operator+=(const Number& n){
512  Poly p2(n);
513  ((PolyBase<POLY_VARIANT_MODUL, Poly>&) (*this))+=p2;
514  return *this;
515  }*/
516  Vector& operator+=(const Vector& p ){
517
[8457864]518    ((Base&)*this)+=p;
[82f499]519    return *this;
520  }
[8457864]521  Vector& operator+=(const Base& p ){
[82f499]522
[8457864]523    ((Base&)*this)+=p;
[82f499]524    return *this;
525  }
[451a9a]526  friend inline bool operator==(const Vector& p1, const Vector& p2);
[6bfb0e]527};
[c1e4cd]528
[6bfb0e]529//typedef Poly PolyBase<POLY_VARIANT_RING>::create_type;
[c1e4cd]530/*template <poly_variant v, class c> inline PolyBase<v> operator+(const PolyBase<v,c>& p1, const PolyBase<v,c>& p2){
[3c7942]531    PolyImpl* res=new PolyImpl(*p1.ptr);
532    *res+=*p2.ptr;
[c1e4cd]533    return(PolyBase<v,c>(*res));
534    }*/
[4e2486]535/*template <poly_variant v> inline PolyBase<v> operator*(const PolyBase<v>& p1, const PolyBase<v>& p2){
[b4e3724]536    PolyImpl* res=new PolyImpl(*p1.ptr);
537    *res *= *p2.ptr;
[ecbe9f7]538    return(PolyBase<v> (*res));
[4e2486]539    }*/
[c1e4cd]540/*template <class c> inline PolyBase<POLY_VARIANT_MODUL> operator*(const PolyBase<POLY_VARIANT_MODUL>& p1, const Number& n){
[4e2486]541  PolyBase<POLY_VARIANT_MODUL> erg(p1);
542  erg*=n;
543  return erg;
[c1e4cd]544  }*/
[c300eca]545inline Poly operator*(const Poly& p, const Poly& p2){
[4e2486]546  Poly erg=p;
547  erg*=p2;
548  return erg;
[49c9e43]549}
[c300eca]550inline Vector operator*(const Number& n, const Vector& v){
[3ffba4f]551  Vector res=v;
552  res*=n;
553  return res;
554}
[096124]555
556//assumes monomials commute with numbers
[a9c298]557template <poly_variant variant, class create_type, class error_traits>
558  inline typename PolyBase<variant,create_type, error_traits>::create_type
[096124]559  operator*
[a9c298]560  (const Number& n,
[8457864]561   const PolyBase<variant,create_type, class error_tratis>& p)
[096124]562{
[8457864]563  typename PolyBase<variant, create_type,error_traits>::create_type erg(p);
[096124]564  erg*=n;
565  return erg;
566}
567
[c300eca]568inline Vector operator*(const Poly& p, const Vector& v){
[9ec8a1]569  Vector res(v);
570  res*=p;
571  return res;
572}
[c300eca]573inline Poly operator+(const Poly& p1, const Number& n){
[82f499]574 Poly f(p1);
575  f+=n;
[6bfb0e]576  return f;
[82f499]577  }
[d964f9]578inline bool operator==(const Poly& p1, const Poly& p2){
579  ring r1=p1.getRing();
580  ring r2=p2.getRing();
581  if (r1!=r2) return false;
582  return p_EqualPolys(p1.ptr->p,p2.ptr->p,r1);
583}
[451a9a]584inline bool operator==(const Vector& p1, const Vector& p2){
585  ring r1=p1.getRing();
586  ring r2=p2.getRing();
587  if (r1!=r2) return false;
588  return p_EqualPolys(p1.ptr->p,p2.ptr->p,r1);
589}
[a9c298]590template <poly_variant variant, class create_type,class error_traits>
591  inline typename PolyBase<variant,create_type,error_traits>::create_type
[82f499]592  operator+
[a9c298]593  (const PolyBase<variant,create_type,error_traits>& b1,
[8457864]594   const PolyBase<variant,create_type,error_traits>& b2)
[82f499]595{
[8457864]596  typename PolyBase<variant, create_type, error_traits>::create_type erg(b1);
[82f499]597  erg+=b2;
598  return erg;
[6bfb0e]599}
[c300eca]600inline Vector unitVector(int i,ring r=currRing){
[9ec8a1]601  poly p=p_ISet(1,r);
602  p_SetComp(p,i,r);
603  return Vector(p,r,0);
604}
[624179]605inline Poly operator*(const Number& n, const Poly & p){
606  Poly res=p;
607  res*=n;
608  return res;
609}
[a9c298]610template <poly_variant variant, class create_type, class error_traits>
611
612inline PolyBase<variant, create_type, error_traits>&
[8457864]613PolyBase<variant, create_type, error_traits>::operator*=(const Poly & p2){
[fd283f]614    copy_on_write();
615    *ptr *= *p2.ptr;
[fea494]616
[fd283f]617    return *this;
618  }
[3c7942]619#endif
Note: See TracBrowser for help on using the repository browser.