1 #ifndef CoCoA_SparsePolyIter_H
2 #define CoCoA_SparsePolyIter_H
3 
4 //   Copyright (c)  2005-2007,2009,2012  John Abbott
5 
6 //   This file is part of the source of CoCoALib, the CoCoA Library.
7 
8 //   CoCoALib is free software: you can redistribute it and/or modify
9 //   it under the terms of the GNU General Public License as published by
10 //   the Free Software Foundation, either version 3 of the License, or
11 //   (at your option) any later version.
12 
13 //   CoCoALib is distributed in the hope that it will be useful,
14 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //   GNU General Public License for more details.
17 
18 //   You should have received a copy of the GNU General Public License
19 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
20 
21 
22 // Header file for the abstract class SparsePolyRingBase etc.
23 
24 #include "CoCoA/PPMonoid.H"
25 #include "CoCoA/ring.H"
26 
27 #include <iosfwd>
28 #include <memory>
29 //using std::uniqe_ptr;
30 
31 namespace CoCoA
32 {
33 
34   class symbol;         // fwd decl -- defined in symbol.H
35   class matrix;         // fwd decl -- defined in matrix.H
36 
37   class SparsePolyIter; // fwd decl -- defined later in this file
38 
39   class SparsePolyIterBase
40   {
41   public:
~SparsePolyIterBase()42     virtual ~SparsePolyIterBase() {};
43     virtual SparsePolyIterBase* myClone() const = 0;
44 
45     virtual bool IamEnded() const = 0;
46     virtual void myForward() = 0;
47 //    virtual SparsePolyIter& operator++() = 0;
48 //    virtual SparsePolyIter operator++(int) = 0;
49     virtual RingElemAlias myCoeff() const = 0;
50     virtual ConstRefPPMonoidElem myPP() const = 0;
51 //    virtual bool operator==(const iter& i2) const = 0;
52 //    virtual bool operator!=(const iter& i2) const = 0;
53   protected:
54     virtual const void* myPolyPtr() const = 0;
55     virtual const void* myTermPtr() const = 0;
56     friend class SparsePolyIter;
57     friend bool operator==(const SparsePolyIter& i1, const SparsePolyIter& i2);
58   };
59 
60   // This is a "smart pointer class" -- it owns the object pointed to.
61   class SparsePolyIter
62   {
63   public:
64     SparsePolyIter(SparsePolyIterBase* ptr);
65     SparsePolyIter(const SparsePolyIter& copy);
66     // Default dtor works OK
67     SparsePolyIter& operator=(const SparsePolyIter& rhs);
68     SparsePolyIterBase* operator->();
69     const SparsePolyIterBase* operator->() const;
70     SparsePolyIter& operator++();
71     SparsePolyIter operator++(int);
72   private:
73     std::unique_ptr<SparsePolyIterBase> myIterPtr;
74     friend bool IsEnded(const SparsePolyIter& i);
75     friend RingElemAlias coeff(const SparsePolyIter& i);
76     friend ConstRefPPMonoidElem PP(const SparsePolyIter& i);
77     friend bool operator==(const SparsePolyIter& i1, const SparsePolyIter& i2);
78   };
79 
80 
81 
82   //--- iterator -------------------------------------
SparsePolyIter(SparsePolyIterBase * ptr)83   inline SparsePolyIter::SparsePolyIter(SparsePolyIterBase* ptr):
84       myIterPtr(ptr)
85   {}
86 
87 
SparsePolyIter(const SparsePolyIter & copy)88   inline SparsePolyIter::SparsePolyIter(const SparsePolyIter& copy):
89       myIterPtr(copy.myIterPtr->myClone())
90   {}
91 
92 
93   inline SparsePolyIter& SparsePolyIter::operator=(const SparsePolyIter& rhs)
94   {
95 //    if (&copy == this.get()) return *this;
96     myIterPtr.reset(rhs.myIterPtr->myClone());
97     return *this;
98   }
99 
100 
101   inline SparsePolyIterBase* SparsePolyIter::operator->()
102   { return myIterPtr.get(); }
103 
104 
105   inline const SparsePolyIterBase* SparsePolyIter::operator->() const
106   { return myIterPtr.get(); }
107 
108 
IsEnded(const SparsePolyIter & i)109   inline bool IsEnded(const SparsePolyIter& i)
110   { return i.myIterPtr->IamEnded(); }
111 
112 
113   inline SparsePolyIter& SparsePolyIter::operator++()
114   {
115     if (myIterPtr->IamEnded()) CoCoA_THROW_ERROR(ERR::PolyIterEnded, "++PolyIter");
116     myIterPtr->myForward();
117     return *this;
118   }
119 
120   inline SparsePolyIter SparsePolyIter::operator++(int)
121   {
122     if (myIterPtr->IamEnded()) CoCoA_THROW_ERROR(ERR::PolyIterEnded, "PolyIter++");
123     SparsePolyIter ans(*this);
124     myIterPtr->myForward();
125     return ans;
126   }
127 
128 
coeff(const SparsePolyIter & i)129   inline RingElemAlias coeff(const SparsePolyIter& i)
130   {
131     if (IsEnded(i)) CoCoA_THROW_ERROR(ERR::PolyIterEnded, "coeff(PolyIter)");
132     return i.myIterPtr->myCoeff();
133   }
134 
135 
PP(const SparsePolyIter & i)136   inline ConstRefPPMonoidElem PP(const SparsePolyIter& i)
137   {
138     if (IsEnded(i)) CoCoA_THROW_ERROR(ERR::PolyIterEnded, "PP(PolyIter)");
139     return i.myIterPtr->myPP();
140   }
141 
142 
143   inline bool operator==(const SparsePolyIter& i1, const SparsePolyIter& i2)
144   {
145     if (i1.myIterPtr->myPolyPtr() != i2.myIterPtr->myPolyPtr())
146       CoCoA_THROW_ERROR(ERR::MixedPolyIters, "PolyIter==PolyIter");
147     return i1.myIterPtr->myTermPtr() == i2.myIterPtr->myTermPtr();
148   }
149 
150 
151   inline bool operator!=(const SparsePolyIter& i1, const SparsePolyIter& i2)
152   { return !(i1==i2); }
153 
154 
155 } // end of namespace CoCoA
156 
157 
158 
159 // RCS header/log in the next few lines
160 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/SparsePolyIter.H,v 1.5 2020/06/17 15:49:20 abbott Exp $
161 // $Log: SparsePolyIter.H,v $
162 // Revision 1.5  2020/06/17 15:49:20  abbott
163 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR
164 //
165 // Revision 1.4  2019/03/04 10:20:08  abbott
166 // Summary: Changed auto_ptr into unqiue_ptr
167 //
168 // Revision 1.3  2018/08/06 16:22:47  abbott
169 // Summary: Added missing include
170 //
171 // Revision 1.2  2018/08/06 13:46:28  bigatti
172 // -- removed useless includes
173 //
174 // Revision 1.1  2018/05/17 15:22:21  bigatti
175 // -- SparsePolyIter separated from SparsePolyRing
176 //
177 
178 #endif
179