Qore Programming Language  0.8.7
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
QoreListNode.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreListNode.h
4 
5  Qore Programming Language
6 
7  Copyright 2003 - 2013 David Nichols
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License aqore_offset_t with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23 
24 #ifndef _QORE_QORELISTNODE_H
25 
26 #define _QORE_QORELISTNODE_H
27 
28 #include <qore/AbstractQoreNode.h>
29 
30 #ifdef min
31 #undef min
32 #endif
33 #ifdef max
34 #undef max
35 #endif
36 
38 
40 
44 class QoreListNode : public AbstractQoreNode {
45  friend class StackList;
46 
47 private:
49  DLLLOCAL QoreListNode(const QoreListNode&);
50 
52  DLLLOCAL QoreListNode& operator=(const QoreListNode&);
53 
54 protected:
56 
58  struct qore_list_private *priv;
59 
60  DLLLOCAL void resize(qore_size_t num);
61  DLLLOCAL QoreListNode* splice_intern(qore_size_t offset, qore_size_t length, ExceptionSink* xsink, bool extract = false);
62  DLLLOCAL QoreListNode* splice_intern(qore_size_t offset, qore_size_t length, const AbstractQoreNode* l, ExceptionSink* xsink, bool extract = false);
63  DLLLOCAL qore_size_t check_offset(qore_offset_t offset);
64  DLLLOCAL void check_offset(qore_offset_t offset, qore_offset_t len, qore_size_t &n_offset, qore_size_t &n_len);
65 
67 
69  DLLLOCAL int qsort(const ResolvedCallReferenceNode* fr, qore_size_t left, qore_size_t right, bool ascending, ExceptionSink* xsink);
70 
72 
74  DLLLOCAL int mergesort(const ResolvedCallReferenceNode* fr, bool ascending, ExceptionSink* xsink);
75 
77  DLLLOCAL QoreListNode* eval_intern(ExceptionSink* xsink) const;
78 
80 
84  DLLEXPORT virtual ~QoreListNode();
85 
87 
93  DLLEXPORT virtual bool derefImpl(ExceptionSink* xsink);
94 
96 
100  DLLEXPORT virtual AbstractQoreNode* evalImpl(ExceptionSink* xsink) const;
101 
103 
106  DLLLOCAL virtual AbstractQoreNode* evalImpl(bool &needs_deref, ExceptionSink* xsink) const;
107 
109  DLLLOCAL virtual int64 bigIntEvalImpl(ExceptionSink* xsink) const;
110 
112  DLLLOCAL virtual int integerEvalImpl(ExceptionSink* xsink) const;
113 
115  DLLLOCAL virtual bool boolEvalImpl(ExceptionSink* xsink) const;
116 
118  DLLLOCAL virtual double floatEvalImpl(ExceptionSink* xsink) const;
119 
120 public:
121  DLLEXPORT QoreListNode();
122 
124 
126  DLLEXPORT virtual bool getAsBoolImpl() const;
127 
129 
135  DLLEXPORT int getAsString(QoreString &str, int foff, ExceptionSink* xsink) const;
136 
138 
145  DLLEXPORT QoreString *getAsString(bool &del, int foff, ExceptionSink* xsink) const;
146 
148  //DLLEXPORT virtual bool needs_eval() const;
149 
151  DLLEXPORT virtual AbstractQoreNode* realCopy() const;
152 
154 
158  DLLEXPORT virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const;
159 
161 
165  DLLEXPORT virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
166 
168  DLLEXPORT virtual const char *getTypeName() const;
169 
171  //DLLEXPORT virtual bool is_value() const;
172 
173  DLLLOCAL static const char *getStaticTypeName() {
174  return "list";
175  }
176 
178 
182  DLLEXPORT AbstractQoreNode* retrieve_entry(qore_size_t index);
183 
185 
189  DLLEXPORT const AbstractQoreNode* retrieve_entry(qore_size_t index) const;
190 
192 
196  DLLEXPORT AbstractQoreNode* get_referenced_entry(qore_size_t index) const;
197 
199 
202  DLLEXPORT int getEntryAsInt(qore_size_t index) const;
203 
207  DLLEXPORT AbstractQoreNode** get_entry_ptr(qore_size_t index);
208 
213 
215 
222  DLLEXPORT void set_entry(qore_size_t index, AbstractQoreNode* val, ExceptionSink* xsink);
223 
224  DLLEXPORT void push(AbstractQoreNode* val);
225  DLLEXPORT void insert(AbstractQoreNode* val);
226 
228 
230  DLLEXPORT AbstractQoreNode* pop();
231 
233 
236  DLLEXPORT AbstractQoreNode* shift();
237 
239  DLLEXPORT void merge(const QoreListNode* list);
240 
246  DLLEXPORT int delete_entry(qore_size_t index, ExceptionSink* xsink);
247 
252  DLLEXPORT void pop_entry(qore_size_t index, ExceptionSink* xsink);
253 
255 
261  DLLEXPORT QoreListNode* evalList(ExceptionSink* xsink) const;
262 
264 
271  DLLEXPORT QoreListNode* evalList(bool &needs_deref, ExceptionSink* xsink) const;
272 
274  DLLEXPORT QoreListNode* copy() const;
275 
277 
280  DLLEXPORT QoreListNode* copyListFrom(qore_size_t index) const;
281 
283 
286  DLLEXPORT QoreListNode* sort() const;
287 
289 
293  DLLEXPORT QoreListNode* sort(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
294 
296 
299  DLLEXPORT QoreListNode* sortStable() const;
300 
302 
306  DLLEXPORT QoreListNode* sortStable(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
307 
309 
312  DLLEXPORT QoreListNode* sortDescending() const;
313 
315 
319  DLLEXPORT QoreListNode* sortDescending(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
320 
322 
325  DLLEXPORT QoreListNode* sortDescendingStable() const;
326 
328 
332  DLLEXPORT QoreListNode* sortDescendingStable(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
333 
335 
338  DLLEXPORT AbstractQoreNode* min() const;
339 
341 
344  DLLEXPORT AbstractQoreNode* max() const;
345 
347 
351  DLLEXPORT AbstractQoreNode* min(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
352 
354 
358  DLLEXPORT AbstractQoreNode* max(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const;
359 
361 
365  DLLEXPORT void splice(qore_offset_t offset, ExceptionSink* xsink);
366 
368 
373  DLLEXPORT void splice(qore_offset_t offset, qore_offset_t length, ExceptionSink* xsink);
374 
376 
384  DLLEXPORT void splice(qore_offset_t offset, qore_offset_t length, const AbstractQoreNode* l, ExceptionSink* xsink);
385 
387 
392  DLLEXPORT QoreListNode* extract(qore_offset_t offset, ExceptionSink* xsink);
393 
395 
401  DLLEXPORT QoreListNode* extract(qore_offset_t offset, qore_offset_t length, ExceptionSink* xsink);
402 
404 
413  DLLEXPORT QoreListNode* extract(qore_offset_t offset, qore_offset_t length, const AbstractQoreNode* l, ExceptionSink* xsink);
414 
416 
418  DLLEXPORT qore_size_t size() const;
419 
421 
423  DLLEXPORT bool empty() const;
424 
426  DLLEXPORT QoreListNode* reverse() const;
427 
429  DLLEXPORT QoreListNode* listRefSelf() const;
430 
432  DLLEXPORT AbstractQoreNode* swap(qore_offset_t offset, AbstractQoreNode* val);
433 
435  DLLEXPORT AbstractQoreNode* takeExists(qore_offset_t offset);
436 
437  // needed only while parsing
439  DLLLOCAL QoreListNode(bool i);
440 
442  DLLLOCAL bool isFinalized() const;
443 
445  DLLLOCAL void setFinalized();
446 
448  DLLLOCAL bool isVariableList() const;
449 
451  DLLLOCAL void setVariableList();
452 
454  DLLLOCAL void clearNeedsEval();
455 
457  DLLLOCAL void setNeedsEval();
458 
460  DLLLOCAL void clear();
461 
463 
467  DLLLOCAL AbstractQoreNode* eval_entry(qore_size_t num, ExceptionSink* xsink) const;
468 
470  DLLLOCAL virtual AbstractQoreNode* parseInit(LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo);
471 
473  DLLLOCAL QoreListNode* parseInitList(LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo);
474 };
475 
476 #include <qore/ReferenceHolder.h>
477 
479 
483 
485 
505 protected:
506  QoreListNode* l;
507  qore_offset_t pos;
508 
510  DLLLOCAL void *operator new(size_t);
511 
512 public:
514 
517  DLLEXPORT ListIterator(QoreListNode* lst, qore_size_t n_pos = -1);
518 
520 
523  DLLEXPORT ListIterator(QoreListNode& lst, qore_size_t n_pos = -1);
524 
526 
531  DLLEXPORT bool next();
532 
534 
540  DLLEXPORT bool prev();
541 
543 
548  DLLEXPORT int set(qore_size_t n_pos);
549 
551  DLLEXPORT AbstractQoreNode* getValue() const;
552 
554  DLLEXPORT AbstractQoreNode** getValuePtr() const;
555 
557  DLLEXPORT AbstractQoreNode* getReferencedValue() const;
558 
560  DLLEXPORT AbstractQoreNode* takeValue();
561 
563  DLLEXPORT bool first() const;
564 
566  DLLEXPORT bool last() const;
567 
568  //DLLEXPORT void setValue(AbstractQoreNode* val, ExceptionSink* xsink) const;
569 
571  DLLLOCAL qore_size_t index() const { return pos; }
572 
574  DLLLOCAL qore_size_t max() const { return l->size(); }
575 
577  DLLLOCAL QoreListNode* getList() { return l; }
578 
580  DLLLOCAL bool empty() const {
581  return l->empty();
582  }
583 
585  DLLLOCAL bool valid() const {
586  return pos == -1 ? false : true;
587  }
588 };
589 
591 
611 protected:
612  const QoreListNode* l;
613  qore_offset_t pos;
614 
615 public:
617 
620  DLLEXPORT ConstListIterator(const QoreListNode* lst, qore_size_t n_pos = -1);
621 
623 
626  DLLEXPORT ConstListIterator(const QoreListNode& lst, qore_size_t n_pos = -1);
627 
629 
634  DLLEXPORT bool next();
635 
637 
643  DLLEXPORT bool prev();
644 
646 
651  DLLEXPORT int set(qore_size_t n_pos);
652 
654  DLLEXPORT const AbstractQoreNode* getValue() const;
655 
657  DLLEXPORT AbstractQoreNode* getReferencedValue() const;
658 
660  DLLEXPORT bool first() const;
661 
663  DLLEXPORT bool last() const;
664 
666  DLLLOCAL qore_size_t index() const { return pos; }
667 
669  DLLLOCAL qore_size_t max() const { return l->size(); }
670 
672  DLLLOCAL const QoreListNode* getList() const { return l; }
673 
675  DLLLOCAL bool empty() const {
676  return l->empty();
677  }
678 
680  DLLLOCAL bool valid() const {
681  return pos == -1 ? false : true;
682  }
683 
685  DLLEXPORT void reset();
686 };
687 
690 private:
691  QoreListNode* val;
692  ExceptionSink* xsink;
693  bool needs_deref;
694 
695  DLLLOCAL void discard_intern() {
696  if (needs_deref && val)
697  val->deref(xsink);
698  }
699 
700  DLLLOCAL void eval_intern(const QoreListNode* exp) {
701  if (exp)
702  val = exp->evalList(needs_deref, xsink);
703  else {
704  val = 0;
705  needs_deref = false;
706  }
707  }
708 
712  DLLLOCAL QoreListNodeEvalOptionalRefHolder& operator=(const QoreListNodeEvalOptionalRefHolder&);
714  DLLLOCAL void *operator new(size_t);
715 
716 public:
718  DLLLOCAL QoreListNodeEvalOptionalRefHolder(ExceptionSink* n_xsink) : xsink(n_xsink) {
719  needs_deref = false;
720  val = 0;
721  }
722 
724  DLLLOCAL QoreListNodeEvalOptionalRefHolder(const QoreListNode* exp, ExceptionSink* n_xsink) : xsink(n_xsink) {
725  eval_intern(exp);
726  }
727 
730  discard_intern();
731  }
732 
734  DLLLOCAL void discard() {
735  discard_intern();
736  needs_deref = false;
737  val = 0;
738  }
739 
741  DLLLOCAL void assignEval(const QoreListNode* exp) {
742  discard_intern();
743  eval_intern(exp);
744  }
745 
747  DLLLOCAL void assign(bool n_needs_deref, QoreListNode* n_val) {
748  discard_intern();
749  needs_deref = n_needs_deref;
750  val = n_val;
751  }
752 
754  DLLLOCAL bool needsDeref() const {
755  return needs_deref;
756  }
757 
759 
764  if (needs_deref)
765  needs_deref = false;
766  else if (val)
767  val->ref();
768  return val;
769  }
770 
772  DLLLOCAL void edit() {
773  if (!val) {
774  val = new QoreListNode;
775  needs_deref = true;
776  }
777  else if (!needs_deref || !val->is_unique()) {
778  val = val->copy();
779  needs_deref = true;
780  }
781  }
782 
784 
788  DLLLOCAL const QoreListNode* operator->() const { return val; }
789 
791  DLLLOCAL const QoreListNode* operator*() const { return val; }
792 
794  DLLLOCAL operator bool() const { return val != 0; }
795 };
796 
797 #endif