diff --git a/uppsrc/CodeEditor/CodeEditor.cpp b/uppsrc/CodeEditor/CodeEditor.cpp index 44f228225..4fe31a2af 100644 --- a/uppsrc/CodeEditor/CodeEditor.cpp +++ b/uppsrc/CodeEditor/CodeEditor.cpp @@ -213,8 +213,8 @@ void CodeEditor::CopyWord() { if(iscidl(GetChar(p)) || (p > 0 && iscidl(GetChar(--p)))) { int e = GetLength(); int f = p; - while(--p >= 0 && iscidl(GetChar(p))); - ++p; + while(--p >= 0 && iscidl(GetChar(p))) {} + ++p; while(++f < e && iscidl(GetChar(f))); WString txt = GetW(p, f - p); WriteClipboardUnicodeText(txt); diff --git a/uppsrc/CodeEditor/CodeEditor.h b/uppsrc/CodeEditor/CodeEditor.h index b6c179be4..f1f75d3bd 100644 --- a/uppsrc/CodeEditor/CodeEditor.h +++ b/uppsrc/CodeEditor/CodeEditor.h @@ -70,7 +70,6 @@ private: Vector li; LineInfoRem li_removed; - int sy; CodeEditor *editor; int ptrline[2]; Image ptrimg[2]; @@ -114,7 +113,7 @@ public: LineInfo GetLineInfo() const; void SetLineInfo(const LineInfo& li, int total); LineInfoRem & GetLineInfoRem() { return li_removed; } - void SetLineInfoRem(pick_ LineInfoRem& li) { li_removed = li; } + void SetLineInfoRem(LineInfoRem pick_ li) { li_removed = pick(li); } void SetAnnotation(int line, const Image& img, const String& ann); String GetAnnotation(int line) const; @@ -492,7 +491,7 @@ public: LineInfo GetLineInfo() const { return bar.GetLineInfo(); } void SetLineInfo(const LineInfo& lf); LineInfoRem GetLineInfoRem() { return LineInfoRem(bar.GetLineInfoRem(), 0); } - void SetLineInfoRem(pick_ LineInfoRem& lf) { bar.SetLineInfoRem(LineInfoRem(lf, 0)); } + void SetLineInfoRem(LineInfoRem pick_ lf) { bar.SetLineInfoRem(LineInfoRem(lf, 0)); } double GetStatEditTime() const { return stat_edit_time; } void Renumber() { bar.Renumber(GetLineCount()); } void ClearBreakpoints() { bar.ClearBreakpoints(); } diff --git a/uppsrc/CodeEditor/EditorBar.cpp b/uppsrc/CodeEditor/EditorBar.cpp index 79fb3d19a..f62d2471c 100644 --- a/uppsrc/CodeEditor/EditorBar.cpp +++ b/uppsrc/CodeEditor/EditorBar.cpp @@ -32,7 +32,7 @@ void Renumber(LineInfo& lf) } l += r.count; } - lf = tf; + lf = pick(tf); } void ClearBreakpoints(LineInfo& lf) @@ -130,7 +130,7 @@ void EditorBar::Paint(Draw& w) } } } - previf = nextif; + previf = pick(nextif); } if(editor->GetMarkLines()) { int width = CodeEditorImg::Breakpoint().GetWidth() >> 1; diff --git a/uppsrc/CodeEditor/Highlight.cpp b/uppsrc/CodeEditor/Highlight.cpp index 63e2eceee..13cf93750 100644 --- a/uppsrc/CodeEditor/Highlight.cpp +++ b/uppsrc/CodeEditor/Highlight.cpp @@ -307,6 +307,7 @@ void CodeEditor::InitKeywords() "byte", "word", "dword", "__countof", "pick_", "wchar", "NULL", "Null", "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "qword", "INTERLOCKED_", "INTERLOCKED", "ONCELOCK", "ONCELOCK_", "INITBLOCK", "EXITBLOCK", + "rval_", "rval_default", NULL }; static const char *usc[] = { diff --git a/uppsrc/Core/Algo.h b/uppsrc/Core/Algo.h index 1ba56f129..57ee266a0 100644 --- a/uppsrc/Core/Algo.h +++ b/uppsrc/Core/Algo.h @@ -1547,7 +1547,7 @@ void SortByKey(Map& map, const Less& less) typename Map::KeyContainer k = map.PickKeys(); typename Map::ValueContainer v = map.PickValues(); IndexSort(k, v, less); - map = Map(k, v); + map = Map(pick(k), pick(v)); } template @@ -1562,7 +1562,7 @@ void SortByValue(Map& map, const Less& less) typename Map::KeyContainer k = map.PickKeys(); typename Map::ValueContainer v = map.PickValues(); IndexSort(v, k, less); - map = Map(k, v); + map = Map(pick(k), pick(v)); } template @@ -1577,7 +1577,7 @@ void StableSortByKey(Map& map, const Less& less) typename Map::KeyContainer k = map.PickKeys(); typename Map::ValueContainer v = map.PickValues(); StableIndexSort(k, v, less); - map = Map(k, v); + map = Map(pick(k), pick(v)); } template @@ -1592,7 +1592,7 @@ void StableSortByValue(Map& map, const Less& less) typename Map::KeyContainer k = map.PickKeys(); typename Map::ValueContainer v = map.PickValues(); StableIndexSort(v, k, less); - map = Map(k, v); + map = Map(pick(k), pick(v)); } template @@ -1601,13 +1601,12 @@ void StableSortByValue(Map& map) StableSortByValue(map, StdLess()); } - template void SortIndex(Index& index, const Less& less) { typename Index::ValueContainer k = index.PickKeys(); Sort(k, less); - index = Index(k); + index = Index(pick(k)); } template @@ -1621,7 +1620,7 @@ void StableSortIndex(Index& index, const Less& less) { typename Index::ValueContainer k = index.PickKeys(); StableSort(k, less); - index = Index(k); + index = Index(pick(k)); } template diff --git a/uppsrc/Core/BiCont.h b/uppsrc/Core/BiCont.h index c43f4dec8..da6e1f134 100644 --- a/uppsrc/Core/BiCont.h +++ b/uppsrc/Core/BiCont.h @@ -15,8 +15,8 @@ protected: T *AddHead0() { AssertMoveable(); Add0(); return &vector[start = Ix(alloc - 1)/*(start + alloc - 1) % alloc*/]; } T *AddTail0() { AssertMoveable(); Add0(); return &vector[EI()]; } void Free(); - void Pick(pick_ BiVector& x) { vector = x.vector; start = x.start; items = x.items; - alloc = x.alloc; ((BiVector&)x).items = -1; } + void Pick(BiVector rval_ x) { vector = pick(x.vector); start = x.start; items = x.items; + alloc = x.alloc; ((BiVector&)x).items = -1; } void Copy(T *dst, int start, int count) const; public: @@ -28,8 +28,8 @@ public: T& AddTail() { return *new(AddTail0()) T; } void AddHead(const T& x) { new(AddHead0()) T(x); } void AddTail(const T& x) { new(AddTail0()) T(x); } - void AddHeadPick(pick_ T& x) { new(AddHead0()) T(x); } - void AddTailPick(pick_ T& x) { new(AddTail0()) T(x); } + void AddHeadPick(T rval_ x) { new(AddHead0()) T(x); } + void AddTailPick(T rval_ x) { new(AddTail0()) T(x); } T& Head() { ASSERT(items > 0); return vector[start]; } T& Tail() { ASSERT(items > 0); return vector[EI()]; } const T& Head() const { ASSERT(items > 0); return vector[start]; } @@ -46,13 +46,21 @@ public: #ifdef UPP void Serialize(Stream& s); + String ToString() const; + bool operator==(const BiVector& b) const { return IsEqualArray(*this, b); } + bool operator!=(const BiVector& b) const { return !operator==(b); } + int Compare(const BiVector& b) const { return CompareArray(*this, b); } + bool operator<=(const BiVector& x) const { return Compare(x) <= 0; } + bool operator>=(const BiVector& x) const { return Compare(x) >= 0; } + bool operator<(const BiVector& x) const { return Compare(x) < 0; } + bool operator>(const BiVector& x) const { return Compare(x) > 0; } #endif bool IsPicked() const { return items < 0; } BiVector(const BiVector& src, int) { DeepCopy0(src); } - BiVector(pick_ BiVector& src) { Pick(src); } - void operator=(pick_ BiVector& src) { Free(); Pick(src); } + BiVector(BiVector rval_ src) { Pick(pick(src)); } + void operator=(BiVector rval_ src) { Free(); Pick(pick(src)); } BiVector() { start = items = alloc = 0; vector = NULL; } ~BiVector() { Free(); } // gcc4.0 workaround!! @@ -93,8 +101,8 @@ public: T& AddTail() { T *q = new T; bv.AddTail(q); return *q; } void AddHead(const T& x) { bv.AddHead(DeepCopyNew(x)); } void AddTail(const T& x) { bv.AddTail(DeepCopyNew(x)); } - void AddHeadPick(pick_ T& x) { bv.AddHead(new T(x)); } - void AddTailPick(pick_ T& x) { bv.AddTail(new T(x)); } + void AddHeadPick(T rval_ x) { bv.AddHead(new T(x)); } + void AddTailPick(T rval_ x) { bv.AddTail(new T(x)); } T& AddHead(T *newt) { bv.AddHead(newt); return *newt; } T& AddTail(T *newt) { bv.AddTail(newt); return *newt; } template TT& CreateHead() { TT *q = new TT; bv.AddHead(q); return *q; } @@ -117,14 +125,22 @@ public: #ifdef UPP void Serialize(Stream& s); + String ToString() const; + bool operator==(const BiArray& b) const { return IsEqualArray(*this, b); } + bool operator!=(const BiArray& b) const { return !operator==(b); } + int Compare(const BiArray& b) const { return CompareArray(*this, b); } + bool operator<=(const BiArray& x) const { return Compare(x) <= 0; } + bool operator>=(const BiArray& x) const { return Compare(x) >= 0; } + bool operator<(const BiArray& x) const { return Compare(x) < 0; } + bool operator>(const BiArray& x) const { return Compare(x) > 0; } #endif bool IsPicked() const { return bv.IsPicked(); } BiArray(const BiArray& v, int) { DeepCopy0(v); } - BiArray(pick_ BiArray& src) : bv(src.bv) {} - void operator=(pick_ BiArray& src) { Free(); bv = src.bv; } + BiArray(BiArray rval_ src) : bv(pick(src.bv)) {} + void operator=(BiArray rval_ src) { Free(); bv = pick(src.bv); } BiArray() {} ~BiArray() { Free(); } diff --git a/uppsrc/Core/Complex.h b/uppsrc/Core/Complex.h index 8754297f1..bb217866a 100644 --- a/uppsrc/Core/Complex.h +++ b/uppsrc/Core/Complex.h @@ -17,6 +17,8 @@ struct Complex : std::complex bool operator==(const Complex& c) const { return (const C&)(*this) == (const C&)c; } bool operator!=(const Complex& c) const { return (const C&)(*this) != (const C&)c; } + + int Compare(const Complex& c) const { NEVER(); return 0; } void Serialize(Stream& s); void Xmlize(XmlIO& xio); @@ -32,9 +34,16 @@ template<> inline dword ValueTypeNo(const Complex*) { return COMPLEX_V; } inline const Complex& Nvl(const Complex& a, const Complex& b) { return IsNull(a) ? b : a; } +template<> inline bool IsPolyEqual(const Complex& x, const Value& v) { return IsNumber(v) && x.imag() == 0 && x.real() == (double)v; } +template<> +inline int PolyCompare(const Complex& a, const Value& b) +{ + NEVER(); return 0; +} + VALUE_COMPARE(Complex) NTL_MOVEABLE(Complex) diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index 318c0d72a..1ce8f1178 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -332,6 +332,7 @@ class JsonIO; #include "Vcont.hpp" #include "Map.hpp" #include "InVector.hpp" +#include "InMap.hpp" #if (defined(HEAPDBG) || defined(TESTLEAKS)) && defined(PLATFORM_POSIX) extern int sMemDiagInitCount; diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index ad00d13a2..ac5524dc4 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -91,6 +91,7 @@ file Hash.cpp optimize_speed, InVector.h, InVector.hpp, + InMap.hpp, Tuple.h, Other.h, Concretes readonly separator, diff --git a/uppsrc/Core/Defs.h b/uppsrc/Core/Defs.h index 3eab534ef..3bf5159a9 100644 --- a/uppsrc/Core/Defs.h +++ b/uppsrc/Core/Defs.h @@ -378,10 +378,36 @@ inline bool IsFin(double d) { return !IsNaN(d) && !IsInf(d); } #define OFFSETOF(clss, mbr) ((int)(uintptr_t)&(((clss *)1)->mbr) - 1) +template +T clone(const T& x) { T c(x, 1); return c; } + +#ifdef CPP_11 + +#define pick_ +#define rval_ && +#define rval_default(T) T(T&&) = default; T& operator=(T&&) = default; + +template +T&& pick(T& x) { return static_cast(x); } + +#else + +template +T& pick(T& x) { return x; } + #ifdef COMPILER_MSC #define pick_ +#define rval_ & #else #define pick_ const +#define rval_ const & +#endif + +#define rval_default(T) + +template +T& pick(const T& x) { return const_cast(x); } + #endif #define init_ @@ -566,7 +592,7 @@ int CPU_Cores(); bool IsDecentMachine(); template -inline void Swap(T& a, T& b) { T tmp = a; a = b; b = tmp; } +inline void Swap(T& a, T& b) { T tmp = pick(a); a = pick(b); b = pick(tmp); } #if defined(CPU_UNALIGNED) && defined(CPU_LE) inline int Peek16le(const void *ptr) { return *(const word *)ptr; } diff --git a/uppsrc/Core/FixedMap.h b/uppsrc/Core/FixedMap.h index 2c198b4a2..a84990333 100644 --- a/uppsrc/Core/FixedMap.h +++ b/uppsrc/Core/FixedMap.h @@ -6,7 +6,7 @@ protected: public: T& Add(const K& k, const T& x) { key.Add(k); return value.Add(x); } - T& AddPick(const K& k, pick_ T& x) { key.Add(k); return value.AddPick(x); } + T& AddPick(const K& k, T rval_ x) { key.Add(k); return value.AddPick(x); } T& Add(const K& k) { key.Add(k); return value.Add(); } void Finish() { IndexSort(key, value, Less()); Shrink(); } @@ -36,16 +36,17 @@ public: void Serialize(Stream& s); void Xmlize(XmlIO& xio); void Jsonize(JsonIO& jio); + String ToString() const; #endif void Swap(FixedAMap& x) { UPP::Swap(value, x.value); UPP::Swap(key, x.key); } const Vector& GetKeys() const { return key; } - Vector PickKeys() pick_ { return key; } + Vector PickKeys() { return pick(key); } const V& GetValues() const { return value; } V& GetValues() { return value; } - V PickValues() pick_ { return value; } + V PickValues() { return pick(value); } bool IsPicked() const { return value.IsPicked() || key.IsPicked(); } @@ -53,7 +54,7 @@ public: FixedAMap() {} FixedAMap(const FixedAMap& s, int) : key(s.key, 0), value(s.value, 0) {} - FixedAMap(pick_ Vector& key, pick_ V& val) : key(key), value(val) {} + FixedAMap(Vector rval_ key, V rval_ val) : key(key), value(val) {} typedef Vector KeyContainer; typedef K KeyType; @@ -82,7 +83,7 @@ class FixedVectorMap : public MoveableAndDeepCopyOption, Less > B; public: FixedVectorMap(const FixedVectorMap& s, int) : FixedAMap, Less>(s, 1) {} - FixedVectorMap(pick_ Vector& key, pick_ Vector& val) : FixedAMap, Less>(key, val) {} + FixedVectorMap(Vector rval_ key, Vector rval_ val) : FixedAMap, Less>(key, val) {} FixedVectorMap() {} friend void Swap(FixedVectorMap& a, FixedVectorMap& b) { a.B::Swap(b); } @@ -103,7 +104,7 @@ public: template TT& Create(const K& k) { TT *q = new TT; B::key.Add(k); return static_cast(B::value.Add(q)); } FixedArrayMap(const FixedArrayMap& s, int) : FixedAMap, Less>(s, 1) {} - FixedArrayMap(pick_ Vector& ndx, pick_ Array& val) : FixedAMap, Less>(ndx, val) {} + FixedArrayMap(Vector rval_ ndx, Array rval_ val) : FixedAMap, Less>(ndx, val) {} FixedArrayMap() {} friend void Swap(FixedArrayMap& a, FixedArrayMap& b) { a.B::Swap(b); } diff --git a/uppsrc/Core/Gtypes.h b/uppsrc/Core/Gtypes.h index b2ddd4c4e..bc3fca930 100644 --- a/uppsrc/Core/Gtypes.h +++ b/uppsrc/Core/Gtypes.h @@ -80,6 +80,9 @@ struct Size_ : Moveable< Size_ > { void Serialize(Stream& s) { s % cx % cy; } void Jsonize(JsonIO& jio) { jio("cx", cx)("cy", cy); } void Xmlize(XmlIO& xio) { xio.Attr("cx", cx).Attr("cy", cy); } + + int Compare(const Size_&) const { NEVER(); return 0; } + int PolyCompare(const Value&) const { NEVER(); return 0; } #ifdef PLATFORM_WIN32 operator SIZE*() { ASSERT(sizeof(*this) == sizeof(SIZE)); return (SIZE*)this; } @@ -187,6 +190,9 @@ struct Point_ : Moveable< Point_ > { void Jsonize(JsonIO& jio) { jio("x", x)("y", y); } void Xmlize(XmlIO& xio) { xio.Attr("x", x).Attr("y", y); } + int Compare(const Point_&) const { NEVER(); return 0; } + int PolyCompare(const Value&) const { NEVER(); return 0; } + #ifdef PLATFORM_WIN32 operator POINT*() { ASSERT(sizeof(*this) == sizeof(POINT)); return (POINT*)this; } operator const POINT*() const { ASSERT(sizeof(*this) == sizeof(POINT)); return (POINT*)this; } @@ -370,6 +376,9 @@ struct Rect_ : Moveable< Rect_ > { void Jsonize(JsonIO& jio) { jio("left", left)("top", top)("right", right)("bottom", bottom); } void Xmlize(XmlIO& xio) { xio.Attr("left", left).Attr("top", top).Attr("right", right).Attr("bottom", bottom); } + int Compare(const Rect_&) const { NEVER(); return 0; } + int PolyCompare(const Value&) const { NEVER(); return 0; } + #ifdef PLATFORM_WIN32 operator const RECT*() const { ASSERT(sizeof(*this) == sizeof(RECT)); return (RECT*)this; } operator RECT*() { ASSERT(sizeof(*this) == sizeof(RECT)); return (RECT*)this; } diff --git a/uppsrc/Core/Hash.cpp b/uppsrc/Core/Hash.cpp index d0103b5dc..4e54b3015 100644 --- a/uppsrc/Core/Hash.cpp +++ b/uppsrc/Core/Hash.cpp @@ -57,9 +57,9 @@ HashBase::HashBase() mcount = 0; } -HashBase::HashBase(pick_ HashBase& b) -: hash(b.hash), - link(b.link) +HashBase::HashBase(HashBase rval_ b) +: hash(pick(b.hash)), + link(pick(b.link)) { map = b.map; mcount = b.mcount; @@ -67,10 +67,10 @@ HashBase::HashBase(pick_ HashBase& b) const_cast(b).map = NULL; } -void HashBase::operator=(pick_ HashBase& b) +void HashBase::operator=(HashBase rval_ b) { - hash = b.hash; - link = b.link; + hash = pick(b.hash); + link = pick(b.link); Free(); map = b.map; mcount = b.mcount; diff --git a/uppsrc/Core/InVector.h b/uppsrc/Core/InVector.h index b54fd48d3..f914a8a7d 100644 --- a/uppsrc/Core/InVector.h +++ b/uppsrc/Core/InVector.h @@ -1,6 +1,3 @@ -template -class SortedAMap; - template struct Slaved_InVector__; template struct Slaved_InArray__; @@ -15,7 +12,6 @@ struct InVectorSlave__ { virtual void RemoveBlk(int blki, int n) = 0; virtual void Index(int blki, int n) = 0; virtual void Reindex() = 0; -// virtual void Serialize(Stream& s) = 0; virtual void Shrink() = 0; }; @@ -25,7 +21,8 @@ public: class ConstIterator; class Iterator; - template friend class SortedAMap; + template friend class SortedAMap; + template friend class SortedVectorMap; template friend struct Slaved_InVector__; template friend struct Slaved_InArray__; @@ -71,7 +68,7 @@ private: void SetBegin(ConstIterator& it) const; void SetEnd(ConstIterator& it) const; - void Chk() const { ASSERT_(!IsPicked(), "Broken pick semantics"); } + void Chk() const { ASSERT_(!IsPicked(), "Broken rval_ semantics"); } #ifdef flagIVTEST void Check(int blki, int offset) const; @@ -148,6 +145,14 @@ public: void Serialize(Stream& s) { StreamContainer(s, *this); } void Xmlize(XmlIO& xio, const char *itemtag = "item"); void Jsonize(JsonIO& jio); + String ToString() const; + bool operator==(const InVector& b) const { return IsEqualArray(*this, b); } + bool operator!=(const InVector& b) const { return !operator==(b); } + int Compare(const InVector& b) const { return CompareArray(*this, b); } + bool operator<=(const InVector& x) const { return Compare(x) <= 0; } + bool operator>=(const InVector& x) const { return Compare(x) >= 0; } + bool operator<(const InVector& x) const { return Compare(x) < 0; } + bool operator>(const InVector& x) const { return Compare(x) > 0; } #endif friend void Swap(InVector& a, InVector& b) { a.Swap(b); } @@ -236,7 +241,7 @@ public: template class InArray : public MoveableAndDeepCopyOption< InVector > { - template friend class SortedAMap; +// template friend class SortedAMap; template friend struct Slaved_InArray__; public: @@ -347,15 +352,26 @@ public: bool IsPicked() const { return iv.IsPicked(); } InArray() {} + InArray(InArray rval_ v) : iv(pick(v.iv)) {} + InArray& operator=(InArray rval_ v) { Free(); iv.operator=(pick(v.iv)); return *this; } InArray(const InArray& v, int); + ~InArray() { Free(); } void Swap(InArray& b) { iv.Swap(b.iv); } #ifdef UPP - void Serialize(Stream& s) { StreamContainer(s, *this); } + void Serialize(Stream& s) { StreamContainer(s, *this); } void Xmlize(XmlIO& xio, const char *itemtag = "item"); void Jsonize(JsonIO& jio); + String ToString() const; + bool operator==(const InArray& b) const { return IsEqualArray(*this, b); } + bool operator!=(const InArray& b) const { return !operator==(b); } + int Compare(const InArray& b) const { return CompareArray(*this, b); } + bool operator<=(const InArray& x) const { return Compare(x) <= 0; } + bool operator>=(const InArray& x) const { return Compare(x) >= 0; } + bool operator<(const InArray& x) const { return Compare(x) < 0; } + bool operator>(const InArray& x) const { return Compare(x) > 0; } #endif friend void Swap(InArray& a, InArray& b) { a.Swap(b); } @@ -439,6 +455,7 @@ template > class SortedIndex : MoveableAndDeepCopyOption< SortedIndex > { InVector iv; + template friend class SortedVectorMap; template friend class SortedAMap; public: @@ -479,9 +496,10 @@ public: const InVector& GetKeys() const { return iv; } - SortedIndex() {} SortedIndex(const SortedIndex& s, int) : iv(s.iv, 1) {} + + bool IsPicked() const { return iv.IsPicked(); } void Swap(SortedIndex& a) { iv.Swap(a.iv); } @@ -489,6 +507,14 @@ public: void Serialize(Stream& s) { iv.Serialize(s); } void Xmlize(XmlIO& xio, const char *itemtag = "key") { iv.Xmlize(xio, itemtag); } void Jsonize(JsonIO& jio) { iv.Jsonize(jio); } + String ToString() const; + bool operator==(const SortedIndex& b) const { return IsEqualArray(*this, b); } + bool operator!=(const SortedIndex& b) const { return !operator==(b); } + int Compare(const SortedIndex& b) const { return CompareArray(*this, b); } + bool operator<=(const SortedIndex& x) const { return Compare(x) <= 0; } + bool operator>=(const SortedIndex& x) const { return Compare(x) >= 0; } + bool operator<(const SortedIndex& x) const { return Compare(x) < 0; } + bool operator>(const SortedIndex& x) const { return Compare(x) > 0; } #endif friend void Swap(SortedIndex& a, SortedIndex& b){ a.Swap(b); } @@ -497,13 +523,13 @@ public: }; template -class SortedAMap : MoveableAndDeepCopyOption< SortedAMap > { +class SortedAMap { protected: SortedIndex key; - Data value; + Data value; - void SetSlave() { key.iv.SetSlave(&value); } - T& At(int i) const { int blki = key.iv.FindBlock(i); return value.Get(blki, i); } + void SetSlave() { key.iv.SetSlave(&value); } + T& At(int i) const { return (T&)value.data[i]; } public: int FindLowerBound(const K& k) const { return key.FindLowerBound(k); } @@ -516,14 +542,16 @@ public: T& Get(const K& k) { return At(Find(k)); } const T& Get(const K& k) const { return At(Find(k)); } - const T& Get(const K& k, const T& d) const { int i = Find(k); return i >= 0 ? value[i] : d; } + const T& Get(const K& k, const T& d) const { int i = Find(k); return i >= 0 ? At(i) : d; } - T *FindPtr(const K& k) { int i = Find(k); return i >= 0 ? &value[i] : NULL; } - const T *FindPtr(const K& k) const { int i = Find(k); return i >= 0 ? &value[i] : NULL; } + T *FindPtr(const K& k) { int i = Find(k); return i >= 0 ? &At(i) : NULL; } + const T *FindPtr(const K& k) const { int i = Find(k); return i >= 0 ? &At(i) : NULL; } - const K& GetKey(int i) const { return key[i]; } const T& operator[](int i) const { return At(i); } T& operator[](int i) { return At(i); } + + const K& GetKey(int i) const { return key[i]; } + int GetCount() const { return key.GetCount(); } bool IsEmpty() const { return key.IsEmpty(); } void Clear() { key.Clear(); } @@ -533,22 +561,19 @@ public: void Remove(int i, int count) { key.Remove(i, count); } int RemoveKey(const K& k) { return key.RemoveKey(k); } - void Drop(int n = 1) { key.Drop(n); } - T& Top() { return value.Top(); } - const T& Top() const { return value.Top(); } - const K& TopKey() const { return key.Top(); } - K PopKey() { K h = TopKey(); Drop(); return h; } - void Trim(int n) { key.Trim(n); } - - void Swap(SortedAMap& x) { Swap(value, x.value); Swap(key, x.key); } - - bool IsPicked() const { return value.IsPicked() || key.IsPicked(); } - const SortedIndex& GetIndex() const { return key; } const InVector& GetKeys() const { return key.GetKeys(); } - SortedAMap() { SetSlave(); } - SortedAMap(const SortedAMap& s, int) : key(s.key, 0), value(s.value, 0) { SetSlave(); } + bool IsPicked() const { return value.data.IsPicked() || key.IsPicked(); } + + String ToString() const; + bool operator==(const SortedAMap& b) const { return IsEqualMap(*this, b); } + bool operator!=(const SortedAMap& b) const { return !operator==(b); } + int Compare(const SortedAMap& b) const { return CompareMap(*this, b); } + bool operator<=(const SortedAMap& x) const { return Compare(x) <= 0; } + bool operator>=(const SortedAMap& x) const { return Compare(x) >= 0; } + bool operator<(const SortedAMap& x) const { return Compare(x) < 0; } + bool operator>(const SortedAMap& x) const { return Compare(x) > 0; } typedef K KeyType; @@ -557,24 +582,13 @@ public: KeyConstIterator KeyBegin() const { return key.Begin(); } KeyConstIterator KeyEnd() const { return key.End(); } KeyConstIterator KeyGetIter(int pos) const { return key.GetIter(pos); } - - typedef T ValueType; - typedef typename Data::Type::ConstIterator ConstIterator; - typedef typename Data::Type::Iterator Iterator; - - Iterator Begin() { return value.data.Begin(); } - Iterator End() { return value.data.End(); } - Iterator GetIter(int pos) { return value.data.GetIter(pos); } - ConstIterator Begin() const { return value.data.Begin(); } - ConstIterator End() const { return value.data.End(); } - ConstIterator GetIter(int pos) const { return value.data.GetIter(pos); } }; template struct Slaved_InVector__ : InVectorSlave__ { typedef InVector Type; InVector data; - const T *ptr; + T *res; virtual void Clear() { data.Clear(); } virtual void Count(int n) { data.count += n; } @@ -593,28 +607,29 @@ struct Slaved_InVector__ : InVectorSlave__ { }; template > -class SortedVectorMap : public MoveableAndDeepCopyOption >, - public SortedAMap > { - typedef SortedAMap > B; - +class SortedVectorMap : public SortedAMap >, + public MoveableAndDeepCopyOption > { + typedef Slaved_InVector__ Data; + typedef SortedAMap B; + public: - T& Add(const K& k, const T& x) { B::value.ptr = &x; B::key.Add(k); return *(T*)B::value.ptr; } - T& Add(const K& k) { B::value.ptr = NULL; B::key.Add(k); return *(T*)B::value.ptr; } + T& Add(const K& k) { B::key.Add(k); return *B::value.res; } + T& Add(const K& k, const T& x) { B::key.Add(k); *B::value.res = x; return *B::value.res; } - int FindAdd(const K& k) { B::value.ptr = NULL; return B::key.FindAdd(k); } - int FindAdd(const K& k, const T& init) { B::value.ptr = &init; return B::key.FindAdd(k); } + int FindAdd(const K& k) { return B::key.FindAdd(k); } + int FindAdd(const K& k, const T& init); T& GetAdd(const K& k) { return B::At(FindAdd(k)); } T& GetAdd(const K& k, const T& x) { return B::At(FindAdd(k, x)); } - T Pop() { T h = B::Top(); B::Drop(); return h; } - SortedVectorMap& operator()(const K& k, const T& v) { Add(k, v); return *this; } - const InVector& GetValues() const { return B::value.data; } + SortedVectorMap() { B::SetSlave(); } + SortedVectorMap(SortedVectorMap rval_); + SortedVectorMap& operator=(SortedVectorMap rval_); + SortedVectorMap(const SortedVectorMap& s, int); - SortedVectorMap(const SortedVectorMap& s, int) : B(s, 1) {} - SortedVectorMap() {} + void Swap(SortedVectorMap& x); #ifdef UPP void Serialize(Stream& s); @@ -622,10 +637,21 @@ public: void Jsonize(JsonIO& jio); #endif + const InVector& GetValues() const { return B::value.data; } + friend void Swap(SortedVectorMap& a, SortedVectorMap& b) { a.Swap(b); } - typedef typename B::ConstIterator ConstIterator; - typedef typename B::Iterator Iterator; + typedef T ValueType; + typedef typename Data::Type::ConstIterator ConstIterator; + typedef typename Data::Type::Iterator Iterator; + + Iterator Begin() { return B::value.data.Begin(); } + Iterator End() { return B::value.data.End(); } + Iterator GetIter(int pos) { return B::value.data.GetIter(pos); } + ConstIterator Begin() const { return B::value.data.Begin(); } + ConstIterator End() const { return B::value.data.End(); } + ConstIterator GetIter(int pos) const { return B::value.data.GetIter(pos); } + STL_MAP_COMPATIBILITY(SortedVectorMap) }; @@ -633,8 +659,7 @@ template struct Slaved_InArray__ : InVectorSlave__ { typedef InArray Type; InArray data; - T *ptr; - bool mk; + T *res; virtual void Clear() { data.Clear(); } virtual void Count(int n) { data.iv.count += n; } @@ -651,23 +676,22 @@ struct Slaved_InArray__ : InVectorSlave__ { T& Get(int blki, int i) const { return *(T*)data.iv.data[blki][i]; } T *Detach(int i) { T *x = data.iv[i]; data.iv[i] = NULL; return x; } - - Slaved_InArray__() { mk = false; } }; template > class SortedArrayMap : public MoveableAndDeepCopyOption >, public SortedAMap > { - typedef SortedAMap > B; + typedef Slaved_InArray__ Data; + typedef SortedAMap B; public: - T& Add(const K& k, const T& x) { B::value.ptr = new T(x); B::key.Add(k); return *(T*)B::value.ptr; } - T& Add(const K& k) { B::value.ptr = new T; B::key.Add(k); return *(T*)B::value.ptr; } - T& Add(const K& k, T *newt) { B::value.ptr = newt; B::key.Add(k); return *newt; } - template TT& Create(const K& k) { TT *q = new TT; B::value.ptr = q; B::key.Add(k); return *q; } + T& Add(const K& k, const T& x) { B::value.res = DeepCopyNew(x); B::key.Add(k); return *(T*)B::value.res; } + T& Add(const K& k) { B::value.res = NULL; B::key.Add(k); return *(T*)B::value.res; } + T& Add(const K& k, T *newt) { B::value.res = newt; B::key.Add(k); return *newt; } + template TT& Create(const K& k) { TT *q = new TT(); B::value.res = q; B::key.Add(k); return *q; } - int FindAdd(const K& k) { B::value.ptr = NULL; return B::key.FindAdd(k); } - int FindAdd(const K& k, const T& init) { B::value.ptr = (T*)&init; B::value.mk = true; int x = B::key.FindAdd(k); B::value.mk = false; return x; } + int FindAdd(const K& k) { B::value.res = NULL; return B::key.FindAdd(k); } + int FindAdd(const K& k, const T& init); T& GetAdd(const K& k) { return B::At(FindAdd(k)); } T& GetAdd(const K& k, const T& x) { return B::At(FindAdd(k, x)); } @@ -679,8 +703,10 @@ public: SortedArrayMap& operator()(const K& k, const T& v) { Add(k, v); return *this; } - SortedArrayMap(const SortedArrayMap& s, int) : B(s, 1) {} - SortedArrayMap() {} + SortedArrayMap() { B::SetSlave(); } + SortedArrayMap(SortedArrayMap rval_); + SortedArrayMap& operator=(SortedArrayMap rval_); + SortedArrayMap(const SortedArrayMap& s, int); #ifdef UPP void Serialize(Stream& s); @@ -688,9 +714,21 @@ public: void Jsonize(JsonIO& jio); #endif + void Swap(SortedArrayMap& x); + friend void Swap(SortedArrayMap& a, SortedArrayMap& b) { a.Swap(b); } - typedef typename B::ConstIterator ConstIterator; - typedef typename B::Iterator Iterator; + typedef T ValueType; + typedef typename Data::Type::ConstIterator ConstIterator; + typedef typename Data::Type::Iterator Iterator; + + Iterator Begin() { return B::value.data.Begin(); } + Iterator End() { return B::value.data.End(); } + Iterator GetIter(int pos) { return B::value.data.GetIter(pos); } + ConstIterator Begin() const { return B::value.data.Begin(); } + ConstIterator End() const { return B::value.data.End(); } + ConstIterator GetIter(int pos) const { return B::value.data.GetIter(pos); } + STL_MAP_COMPATIBILITY(SortedArrayMap) }; + diff --git a/uppsrc/Core/InVector.hpp b/uppsrc/Core/InVector.hpp index 68562aa41..37a9e96cf 100644 --- a/uppsrc/Core/InVector.hpp +++ b/uppsrc/Core/InVector.hpp @@ -310,7 +310,7 @@ void InVector::InsertN(int ii, int n) template void InVector::Join(int blki) { - data[blki].AppendPick(data[blki + 1]); + data[blki].AppendPick(pick(data[blki + 1])); data.Remove(blki + 1); } @@ -434,6 +434,7 @@ InVector::InVector(const InVector& v, int) blk_high = v.blk_high; blk_low = v.blk_low; serial = NewInVectorSerial(); + slave = v.slave; } template @@ -631,13 +632,14 @@ void InVector::ConstIterator::PrevBlk() template void InVector::Swap(InVector& b) { - Swap(data, b.data); - Swap(index, b.index); - Swap(count, b.count); - Swap(hcount, b.hcount); - Swap(serial, b.serial); - Swap(blk_high, b.blk_high); - Swap(blk_low, b.blk_low); + Upp::Swap(data, b.data); + Upp::Swap(index, b.index); + Upp::Swap(count, b.count); + Upp::Swap(hcount, b.hcount); + Upp::Swap(serial, b.serial); + Upp::Swap(blk_high, b.blk_high); + Upp::Swap(blk_low, b.blk_low); + Upp::Swap(slave, b.slave); } #ifdef UPP @@ -652,6 +654,13 @@ void InVector::Jsonize(JsonIO& jio) { JsonizeArray, T>(jio, *this); } + +template +String InVector::ToString() const +{ + return AsStringArray(*this); +} + #endif template @@ -785,7 +794,7 @@ InArray::InArray(const InArray& v, int) ConstIterator s = v.Begin(); IVIter it = iv.Begin(); while(n--) - *it++ = new T(*s++); + *it++ = DeepCopyNew(*s++); } #ifdef UPP @@ -800,161 +809,13 @@ void InArray::Jsonize(JsonIO& jio) { JsonizeArray, T>(jio, *this); } -#endif - -template -int SortedIndex::FindAdd(const T& key) -{ - int i = FindLowerBound(key); - if(i == GetCount() || Less()(key, iv[i])) - iv.Insert(i, key); - return i; -} - -template -int SortedIndex::FindNext(int i) const -{ - return i + 1 < iv.GetCount() && !Less()(iv[i], iv[i + 1]) ? i + 1 : -1; -} - -template -int SortedIndex::FindLast(const T& x) const -{ - int i = iv.FindUpperBound(x, Less()); - return i > 0 && !Less()(iv[i - 1], x) ? i - 1 : -1; -} - -template -int SortedIndex::FindPrev(int i) const -{ - return i > 0 && !Less()(iv[i - 1], iv[i]) ? i - 1 : -1; -} - -template -int SortedIndex::RemoveKey(const T& x) -{ - int l = FindLowerBound(x); - int count = FindUpperBound(x) - l; - Remove(l, count); - return count; -} template -void Slaved_InVector__::Insert(int blki, int pos) +String InArray::ToString() const { - if(ptr) - data.data[blki].Insert(pos, *ptr); - else - data.data[blki].Insert(pos); - ptr = &data.data[blki][pos]; + return AsStringArray(*this); } -template -void Slaved_InVector__::Split(int blki, int nextsize) -{ - Vector& x = data.data.Insert(blki + 1); - x.InsertSplit(0, data.data[blki], nextsize); - data.data[blki].Shrink(); -} - -template -void Slaved_InVector__::AddFirst() -{ - if(ptr) - data.data.Add().Add(*ptr); - else - data.data.Add().Add(); - ptr = &data.data[0][0]; -} - -template -void Slaved_InArray__::Insert(int blki, int pos) -{ - data.iv.data[blki].Insert(pos, mk ? new T(*ptr) : ptr ? ptr : new T); -} - -template -void Slaved_InArray__::Split(int blki, int nextsize) -{ - Vector< typename InArray::PointerType >& x = data.iv.data.Insert(blki + 1); - x.InsertSplit(0, data.iv.data[blki], nextsize); -} - -template -void Slaved_InArray__::Remove(int blki, int pos, int n) -{ - Vector< typename InArray::PointerType >& b = data.iv.data[blki]; - for(int i = 0; i < n; i++) - if(b[i + pos]) - delete (T *)b[i + pos]; - b.Remove(pos, n); -} - -template -void Slaved_InArray__::AddFirst() -{ - data.iv.data.Add().Add(mk ? new T(*ptr) : ptr ? ptr : new T); -} - -#ifdef UPP -template -void StreamSortedMap(Stream& s, T& cont) -{ - int n = cont.GetCount(); - s / n; - if(n < 0) { - s.LoadError(); - return; - } - if(s.IsLoading()) { - cont.Clear(); - while(n--) { - K key; - s % key; - s % cont.Add(key); - } - } - else - for(int i = 0; i < cont.GetCount(); i++) { - K key = cont.GetKey(i); - s % key; - s % cont[i]; - } -} - -template -void SortedVectorMap::Serialize(Stream& s) { - StreamSortedMap >(s, *this); -} - -template -void SortedVectorMap::Xmlize(XmlIO& xio) -{ - XmlizeSortedMap >(xio, "key", "value", *this); -} - -template -void SortedVectorMap::Jsonize(JsonIO& jio) -{ - JsonizeSortedMap, K, T>(jio, *this, "key", "value"); -} - -template -void SortedArrayMap::Serialize(Stream& s) { - StreamSortedMap >(s, *this); -} - -template -void SortedArrayMap::Xmlize(XmlIO& xio) -{ - XmlizeSortedMap >(xio, "key", "value", *this); -} - -template -void SortedArrayMap::Jsonize(JsonIO& jio) -{ - JsonizeSortedMap, K, T>(jio, *this, "key", "value"); -} #endif #ifdef LLOG diff --git a/uppsrc/Core/Index.h b/uppsrc/Core/Index.h index 0550cfc7a..3e277df6a 100644 --- a/uppsrc/Core/Index.h +++ b/uppsrc/Core/Index.h @@ -63,8 +63,8 @@ public: HashBase(); ~HashBase(); - HashBase(pick_ HashBase& b); - void operator=(pick_ HashBase& b); + HashBase(HashBase rval_ b); + void operator=(HashBase rval_ b); HashBase(const HashBase& b, int); void operator<<=(const HashBase& b); @@ -166,15 +166,24 @@ public: void Serialize(Stream& s); void Xmlize(XmlIO& xio, const char *itemtag = "key"); void Jsonize(JsonIO& jio); + String ToString() const; + bool operator==(const AIndex& b) const { return IsEqualArray(*this, b); } + bool operator!=(const AIndex& b) const { return !operator==(b); } + int Compare(const AIndex& b) const { return CompareArray(*this, b); } + bool operator<=(const AIndex& x) const { return Compare(x) <= 0; } + bool operator>=(const AIndex& x) const { return Compare(x) >= 0; } + bool operator<(const AIndex& x) const { return Compare(x) < 0; } + bool operator>(const AIndex& x) const { return Compare(x) > 0; } #endif - V PickKeys() pick_ { return key; } + V PickKeys() { return pick(key); } const V& GetKeys() const { return key; } bool IsPicked(void) const { return key.IsPicked(); } // Pick assignment & copy. Picked source can only Clear(), ~AIndex(), operator=, operator<<= - AIndex& operator=(pick_ V& s); + AIndex& operator=(V rval_ s); +// AIndex& operator=(AIndex rval_ s) = default; AIndex& operator<<=(const V& s); // Standard container interface @@ -191,7 +200,7 @@ public: friend int GetCount(const AIndex& v) { return v.GetCount(); } protected: - AIndex(pick_ V& s); + AIndex(V rval_ s); AIndex(const V& s, int); AIndex() {} AIndex(const AIndex& s, int); @@ -205,12 +214,13 @@ public: T Pop() { T x = B::Top(); B::Drop(); return x; } Index() {} - Index(pick_ Index& s) : B(s) {} + Index(Index rval_ s) : B(pick(s)) {} Index(const Index& s, int) : B(s, 1) {} - explicit Index(pick_ Vector& s) : B(s){} + explicit Index(Vector rval_ s) : B(pick(s)) {} Index(const Vector& s, int) : B(s, 1) {} - Index& operator=(pick_ Vector& x) { B::operator=(x); return *this; } + Index& operator=(Vector rval_ x) { B::operator=(pick(x)); return *this; } + Index& operator=(Index rval_ x) { B::operator=(pick(x)); return *this; } friend void Swap(Index& a, Index& b) { a.B::Swap(b); } @@ -237,14 +247,15 @@ public: T *Detach(int i) { B::hash.Remove(i); return B::key.Detach(i); } ArrayIndex() {} - ArrayIndex(pick_ ArrayIndex& s) : B(s) {} - ArrayIndex(const ArrayIndex& s, int) : B(s, 1) {} - explicit ArrayIndex(pick_ Array& s) : B(s) {} - ArrayIndex(const Array& s, int) : B(s, 1) {} + ArrayIndex(ArrayIndex rval_ s) : B(pick(s)) {} + ArrayIndex(const ArrayIndex& s, int) : B(s, 1) {} + explicit ArrayIndex(Array rval_ s) : B(pick(s)) {} + ArrayIndex(const Array& s, int) : B(s, 1) {} - ArrayIndex& operator=(pick_ Array& x) { B::operator=(x); return *this; } + ArrayIndex& operator=(Array rval_ x) { B::operator=(pick(x)); return *this; } + ArrayIndex& operator=(ArrayIndex rval_ x) { B::operator=(pick(x)); return *this; } - friend void Swap(ArrayIndex& a, ArrayIndex& b) { a.B::Swap(b); } + friend void Swap(ArrayIndex& a, ArrayIndex& b) { a.B::Swap(b); } typedef typename B::ConstIterator ConstIterator; // GCC bug (?) STL_INDEX_COMPATIBILITY(ArrayIndex) diff --git a/uppsrc/Core/JSON.h b/uppsrc/Core/JSON.h index a73939517..7a0f811db 100644 --- a/uppsrc/Core/JSON.h +++ b/uppsrc/Core/JSON.h @@ -220,7 +220,7 @@ void JsonizeArray(JsonIO& io, T& array) Jsonize(jio, array[i]); jio.Put(va[i]); } - io.Set(ValueArray(va)); + io.Set(ValueArray(pick(va))); } } @@ -249,7 +249,7 @@ void JsonizeMap(JsonIO& io, T& map, const char *keyid, const char *valueid) item.Add(valueid, StoreAsJsonValue(map[i])); va[i] = item; } - io.Set(ValueArray(va)); + io.Set(ValueArray(pick(va))); } } @@ -276,7 +276,7 @@ void JsonizeSortedMap(JsonIO& io, T& map, const char *keyid, const char *valueid item.Add(valueid, StoreAsJsonValue(map[i])); va[i] = item; } - io.Set(ValueArray(va)); + io.Set(ValueArray(pick(va))); } } @@ -305,7 +305,7 @@ void JsonizeStringMap(JsonIO& io, T& map) index.Add(StoreAsJsonValue(map.GetKey(i))); values.Add(StoreAsJsonValue(map[i])); } - ValueMap vm(index, values); + ValueMap vm(pick(index), pick(values)); io.Set(vm); } } @@ -339,7 +339,7 @@ void JsonizeIndex(JsonIO& io, T& index) for(int i = 0; i < index.GetCount(); i++) if(!index.IsUnlinked(i)) va.Add(StoreAsJsonValue(index[i])); - io.Set(ValueArray(va)); + io.Set(ValueArray(pick(va))); } } diff --git a/uppsrc/Core/Log.cpp b/uppsrc/Core/Log.cpp index 46382f742..50d9cb8e3 100644 --- a/uppsrc/Core/Log.cpp +++ b/uppsrc/Core/Log.cpp @@ -120,7 +120,7 @@ void LogOut::Create(bool append) ::GetUserNameA(user, &w); #endif #else //# - const char *procexepath_(); + const char *procexepath_(void); strcpy(exe, procexepath_()); const char *uenv = getenv("USER"); strcpy(user, uenv ? uenv : "boot"); diff --git a/uppsrc/Core/Map.h b/uppsrc/Core/Map.h index c1caa297f..4a59a90af 100644 --- a/uppsrc/Core/Map.h +++ b/uppsrc/Core/Map.h @@ -6,7 +6,7 @@ protected: public: T& Add(const K& k, const T& x) { key.Add(k); return value.Add(x); } - T& AddPick(const K& k, pick_ T& x) { key.Add(k); return value.AddPick(x); } + T& AddPick(const K& k, T rval_ x) { key.Add(k); return value.AddPick(pick(x)); } T& Add(const K& k) { key.Add(k); return value.Add(); } int Find(const K& k, unsigned h) const { return key.Find(k, h); } @@ -18,15 +18,15 @@ public: int FindAdd(const K& k); int FindAdd(const K& k, const T& init); - int FindAddPick(const K& k, pick_ T& init); + int FindAddPick(const K& k, T rval_ init); int Put(const K& k, const T& x); - int PutPick(const K& k, pick_ T& x); + int PutPick(const K& k, T rval_ x); T& Put(const K& k); int FindPut(const K& k); int FindPut(const K& k, const T& init); - int FindPutPick(const K& k, pick_ T& init); + int FindPutPick(const K& k, T rval_ init); T& Get(const K& k) { return value[Find(k)]; } const T& Get(const K& k) const { return value[Find(k)]; } @@ -35,12 +35,12 @@ public: T& GetAdd(const K& k); T& GetAdd(const K& k, const T& x); - T& GetAddPick(const K& k, pick_ T& x); + T& GetAddPick(const K& k, T rval_ x); T& GetPut(const K& k); T& GetPut(const K& k, const T& x); - T& GetPutPick(const K& k, pick_ T& x); + T& GetPutPick(const K& k, T rval_ x); void SetKey(int i, const K& k) { key.Set(i, k); } @@ -87,19 +87,27 @@ public: void Serialize(Stream& s); void Xmlize(XmlIO& xio); void Jsonize(JsonIO& jio); + String ToString() const; + bool operator==(const AMap& b) const { ASSERT(!HasUnlinked()); return IsEqualMap(*this, b); } + bool operator!=(const AMap& b) const { return !operator==(b); } + int Compare(const AMap& b) const { ASSERT(!HasUnlinked()); return CompareMap(*this, b); } + bool operator<=(const AMap& x) const { return Compare(x) <= 0; } + bool operator>=(const AMap& x) const { return Compare(x) >= 0; } + bool operator<(const AMap& x) const { return Compare(x) < 0; } + bool operator>(const AMap& x) const { return Compare(x) > 0; } #endif void Swap(AMap& x) { UPP::Swap(value, x.value); UPP::Swap(key, x.key); } const Index& GetIndex() const { return key; } - Index PickIndex() pick_ { return key; } + Index PickIndex() { return pick(key); } const Vector& GetKeys() const { return key.GetKeys(); } - Vector PickKeys() pick_ { return key.PickKeys(); } + Vector PickKeys() { return key.PickKeys(); } const V& GetValues() const { return value; } V& GetValues() { return value; } - V PickValues() pick_ { return value; } + V PickValues() { return pick(value); } bool IsPicked() const { return value.IsPicked() || key.IsPicked(); } @@ -107,8 +115,8 @@ public: AMap() {} AMap(const AMap& s, int) : key(s.key, 0), value(s.value, 0) {} - AMap(pick_ Index& ndx, pick_ V& val) : key(ndx), value(val) {} - AMap(pick_ Vector& ndx, pick_ V& val) : key(ndx), value(val) {} + AMap(Index rval_ ndx, V rval_ val) : key(pick(ndx)), value(pick(val)) {} + AMap(Vector rval_ ndx, V rval_ val) : key(pick(ndx)), value(pick(val)) {} typedef Vector KeyContainer; typedef K KeyType; @@ -141,8 +149,8 @@ public: T Pop() { T h = B::Top(); B::Drop(); return h; } VectorMap(const VectorMap& s, int) : AMap, HashFn>(s, 1) {} - VectorMap(pick_ Index& ndx, pick_ Vector& val) : AMap, HashFn>(ndx, val) {} - VectorMap(pick_ Vector& ndx, pick_ Vector& val) : AMap, HashFn>(ndx, val) {} + VectorMap(Index rval_ ndx, Vector rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} + VectorMap(Vector rval_ ndx, Vector rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} VectorMap() {} friend void Swap(VectorMap& a, VectorMap& b) { a.B::Swap(b); } @@ -170,8 +178,8 @@ public: T *Swap(int i, T *newt) { return B::value.Swap(i, newt); } ArrayMap(const ArrayMap& s, int) : AMap, HashFn>(s, 1) {} - ArrayMap(pick_ Index& ndx, pick_ Array& val) : AMap, HashFn>(ndx, val) {} - ArrayMap(pick_ Vector& ndx, pick_ Array& val) : AMap, HashFn>(ndx, val) {} + ArrayMap(Index rval_ ndx, Array rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} + ArrayMap(Vector rval_ ndx, Array rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} ArrayMap() {} friend void Swap(ArrayMap& a, ArrayMap& b) { a.B::Swap(b); } @@ -187,8 +195,8 @@ class SegtorMap : public MoveableAndDeepCopyOption< SegtorMap, HashFn > B; public: SegtorMap(const SegtorMap& s, int) : AMap, HashFn>(s, 1) {} - SegtorMap(pick_ Index& ndx, pick_ Segtor& val) : AMap, HashFn>(ndx, val) {} - SegtorMap(pick_ Vector& ndx, pick_ Segtor& val) : AMap, HashFn>(ndx, val) {} + SegtorMap(Index rval_ ndx, Segtor rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} + SegtorMap(Vector rval_ ndx, Segtor rval_ val) : AMap, HashFn>(pick(ndx), pick(val)) {} SegtorMap() {} friend void Swap(SegtorMap& a, SegtorMap& b) { a.B::Swap(b); } diff --git a/uppsrc/Core/Map.hpp b/uppsrc/Core/Map.hpp index 7c0776dfe..349b084e9 100644 --- a/uppsrc/Core/Map.hpp +++ b/uppsrc/Core/Map.hpp @@ -100,8 +100,8 @@ void AIndex::Hash() { } template -AIndex& AIndex::operator=(pick_ V& s) { - key = s; +AIndex& AIndex::operator=(V rval_ s) { + key = pick(s); hash.Clear(); Hash(); return *this; @@ -116,7 +116,7 @@ AIndex& AIndex::operator<<=(const V& s) { } template -AIndex::AIndex(pick_ V& s) : key(s) { +AIndex::AIndex(V rval_ s) : key(pick(s)) { Hash(); } @@ -246,6 +246,13 @@ void AIndex::Jsonize(JsonIO& jio) { JsonizeIndex, T>(jio, *this); } + +template +String AIndex::ToString() const +{ + return AsStringArray(*this); +} + #endif template @@ -390,7 +397,7 @@ int AMap::FindAdd(const K& k, const T& x) { } template -int AMap::FindAddPick(const K& k, pick_ T& x) { +int AMap::FindAddPick(const K& k, T rval_ x) { unsigned hash = key.hashfn(k); int i = Find(k, hash); if(i < 0) { @@ -415,7 +422,7 @@ int AMap::Put(const K& k, const T& x) } template -int AMap::PutPick(const K& k, pick_ T& x) +int AMap::PutPick(const K& k, T rval_ x) { int i = key.Put(k); if(i < value.GetCount()) @@ -470,7 +477,7 @@ int AMap::FindPut(const K& k, const T& init) } template -int AMap::FindPutPick(const K& k, pick_ T& init) +int AMap::FindPutPick(const K& k, T rval_ init) { unsigned hash = key.hashfn(k); int i = Find(k, hash); @@ -502,7 +509,7 @@ T& AMap::GetAdd(const K& k, const T& x) { } template -T& AMap::GetAddPick(const K& k, pick_ T& x) { +T& AMap::GetAddPick(const K& k, T rval_ x) { unsigned hash = key.hashfn(k); int i = Find(k, hash); if(i >= 0) return value[i]; @@ -522,7 +529,7 @@ T& AMap::GetPut(const K& k, const T& x) { } template -T& AMap::GetPutPick(const K& k, pick_ T& x) { +T& AMap::GetPutPick(const K& k, T rval_ x) { return value[FindAddPick(k, x)]; } @@ -544,6 +551,23 @@ void AMap::Jsonize(JsonIO& jio) { JsonizeMap, K, T>(jio, *this, "key", "value"); } + +template +String AMap::ToString() const +{ + String r; + r = "{"; + for(int i = 0; i < GetCount(); i++) { + if(i) + r << ", "; + if(IsUnlinked(i)) + r << "UNLINKED "; + r << GetKey(i) << ": " << (*this)[i]; + } + r << '}'; + return r; +} + #endif template @@ -585,4 +609,19 @@ void FixedAMap::Jsonize(JsonIO& jio) { JsonizeSortedMap, K, T>(jio, *this, "key", "value"); } + +template +String FixedAMap::ToString() const +{ + String r; + r = "{"; + for(int i = 0; i < GetCount(); i++) { + if(i) + r << ", "; + r << GetKey(i) << ": " << (*this)[i]; + } + r << '}'; + return r; +} + #endif diff --git a/uppsrc/Core/Other.h b/uppsrc/Core/Other.h index 8927c1568..17c508133 100644 --- a/uppsrc/Core/Other.h +++ b/uppsrc/Core/Other.h @@ -26,16 +26,16 @@ class One : MoveableAndDeepCopyOption< One > { void Free() { if(ptr && ptr != (T*)1) delete ptr; } void Chk() const { ASSERT(ptr != (T*)1); } void ChkP() const { Chk(); ASSERT(ptr); } - void Pick(pick_ One& data) { T *p = data.ptr; data.ptr = (T*)1; ptr = p; } + void Pick(One rval_ data) { T *p = data.ptr; data.ptr = (T*)1; ptr = p; } public: void Attach(T *data) { Free(); ptr = data; } - T *Detach() pick_ { ChkP(); T *t = ptr; ptr = NULL; return t; } - T *operator-() pick_ { return Detach(); } + T *Detach() { ChkP(); T *t = ptr; ptr = NULL; return t; } + T *operator-() { return Detach(); } void Clear() { Free(); ptr = NULL; } void operator=(T *data) { Attach(data); } - void operator=(pick_ One& d) { Free(); Pick(d); } + void operator=(One rval_ d) { Free(); Pick(pick(d)); } const T *operator->() const { ChkP(); return ptr; } T *operator->() { ChkP(); return ptr; } @@ -52,10 +52,12 @@ public: bool IsEmpty() const { Chk(); return !ptr; } operator bool() const { return ptr; } + + String ToString() const { return ptr ? AsString(*ptr) : ""; } One() { ptr = NULL; } One(T *newt) { ptr = newt; } - One(pick_ One& p) { Pick(p); } + One(One rval_ p) { Pick(pick(p)); } One(const One& p, int) { ptr = p.IsEmpty() ? NULL : DeepCopyNew(*p); } ~One() { Free(); } }; @@ -77,7 +79,7 @@ class Any : Moveable { BaseData *ptr; void Chk() const { ASSERT(ptr != (void *)1); } - void Pick(pick_ Any& s) { ptr = s.ptr; const_cast(s).ptr = (BaseData *)1; } + void Pick(Any rval_ s) { ptr = s.ptr; const_cast(s).ptr = (BaseData *)1; } public: template T& Create() { Clear(); Data *x = new Data; ptr = x; return x->data; } @@ -90,8 +92,8 @@ public: bool IsEmpty() const { return ptr == NULL; } bool IsPicked() const { return ptr == (void *)1; } - void operator=(pick_ Any& s) { Clear(); Pick(s); } - Any(pick_ Any& s) { Pick(s); } + void operator=(Any rval_ s) { Clear(); Pick(pick(s)); } + Any(Any rval_ s) { Pick(pick(s)); } Any() { ptr = NULL; } ~Any() { Clear(); } @@ -117,8 +119,8 @@ public: Buffer(size_t size, const T& init) { ptr = new T[size]; Fill(ptr, ptr + size, init); } ~Buffer() { if(ptr) delete[] ptr; } - void operator=(pick_ Buffer& v) { if(ptr) delete[] ptr; ptr = v.ptr; v.ptr = NULL; } - Buffer(pick_ Buffer& v) { ptr = v.ptr; v.ptr = NULL; } + void operator=(Buffer rval_ v) { if(ptr) delete[] ptr; ptr = v.ptr; v.ptr = NULL; } + Buffer(Buffer rval_ v) { ptr = v.ptr; v.ptr = NULL; } }; class Bits : Moveable { @@ -136,8 +138,8 @@ public: Bits() { bp = NULL; alloc = 0; } ~Bits() { Clear(); } - Bits(pick_ Bits& b) { alloc = b.alloc; bp = b.bp; b.alloc = -1; } - void operator=(pick_ Bits& b) { Clear(); alloc = b.alloc; bp = b.bp; b.alloc = -1; } + Bits(Bits rval_ b) { alloc = b.alloc; bp = b.bp; b.alloc = -1; } + void operator=(Bits rval_ b) { Clear(); alloc = b.alloc; bp = b.bp; b.alloc = -1; } }; //# System dependent @@ -150,7 +152,7 @@ class Mitor : Moveable< Mitor > { byte elem0[sizeof(T)]; T& Get(int i) const; - void Pick(pick_ Mitor& m); + void Pick(Mitor rval_ m); void Copy(const Mitor& m); void Chk() const { ASSERT(count != 2); } @@ -163,11 +165,11 @@ public: void Clear(); void Shrink(); - Mitor(pick_ Mitor& m) { Pick(m); } - void operator=(pick_ Mitor& m) { Clear(); Pick(m); } + Mitor(Mitor rval_ m) { Pick(m); } + void operator=(Mitor rval_ m) { Clear(); Pick(pick(m)); } Mitor(Mitor& m, int) { Copy(m); } - void operator<<=(const Mitor& m) { Clear(); Copy(m); } + void operator<<=(const Mitor& m) { Clear(); Copy(pick(m)); } Mitor() { count = 0; } ~Mitor() { Clear(); } @@ -181,7 +183,7 @@ T& Mitor::Get(int i) const } template -void Mitor::Pick(pick_ Mitor& m) +void Mitor::Pick(Mitor rval_ m) { m.Chk(); vector = m.vector; diff --git a/uppsrc/Core/Topt.h b/uppsrc/Core/Topt.h index 0d519ed1b..daf728839 100644 --- a/uppsrc/Core/Topt.h +++ b/uppsrc/Core/Topt.h @@ -270,8 +270,8 @@ public: WithDeepCopy(const T& a) : T(a, 1) {} WithDeepCopy(const WithDeepCopy& a) : T(a, 1) {} WithDeepCopy& operator=(const WithDeepCopy& a) { (T&)*this <<= a; return *this; } - WithDeepCopy(int, pick_ T& a) : T(a) {} - WithDeepCopy& operator^=(pick_ T& a) { (T&)*this = a; return *this; } + WithDeepCopy(int, T rval_ a) : T(a) {} + WithDeepCopy& operator^=(T rval_ a) { (T&)*this = pick(a); return *this; } WithDeepCopy() {} }; @@ -518,3 +518,57 @@ inline unsigned GetHashValue(T *ptr) { return GetPtr template inline const T& ntl_max(const T& a, const T& b) { return a > b ? a : b; } +template +struct Data_S_ : Moveable< Data_S_ > +{ + byte filler[size]; +}; + +template +bool IsEqualArray(const C& a, const C& b) +{ + if(a.GetCount() != b.GetCount()) + return false; + for(int i = 0; i < a.GetCount(); i++) + if(!(a[i] == b[i])) + return false; + return true; +} + +template +int CompareArray(const C& a, const C& b) +{ + int n = min(a.GetCount(), b.GetCount()); + for(int i = 0; i < n; i++) { + int q = SgnCompare(a[i], b[i]); + if(q) + return q; + } + return SgnCompare(a.GetCount(), b.GetCount()); +} + +template +bool IsEqualMap(const C& a, const C& b) +{ + if(a.GetCount() != b.GetCount()) + return false; + for(int i = 0; i < a.GetCount(); i++) + if(a.GetKey(i) != b.GetKey(i) || a[i] != b[i]) + return false; + return true; +} + +template +int CompareMap(const C& a, const C& b) +{ + int n = min(a.GetCount(), b.GetCount()); + for(int i = 0; i < n; i++) { + int q = SgnCompare(a.GetKey(i), b.GetKey(i)); + if(q) + return q; + q = SgnCompare(a[i], b[i]); + if(q) + return q; + } + return SgnCompare(a.GetCount(), b.GetCount()); +} diff --git a/uppsrc/Core/Tuple.h b/uppsrc/Core/Tuple.h index 3e46de650..4f55d1b6b 100644 --- a/uppsrc/Core/Tuple.h +++ b/uppsrc/Core/Tuple.h @@ -17,6 +17,9 @@ struct Tuple2 { void Serialize(Stream& s) { s % a % b; } String ToString() const { return String().Cat() << '(' << a << ", " << b << ')'; } + + template + operator Tuple2() const { Tuple2 t; t.a = (AA)a; t.b = (BB)b; return t; } }; template @@ -55,6 +58,9 @@ struct Tuple3 { void Serialize(Stream& s) { s % a % b % c; } String ToString() const { return String().Cat() << '(' << a << ", " << b << ", " << c << ')'; } + + template + operator Tuple3() const { Tuple3 t; t.a = (AA)a; t.b = (BB)b; t.c = (CC)c; return t; } }; template @@ -96,6 +102,9 @@ struct Tuple4 { void Serialize(Stream& s) { s % a % b % c % d; } String ToString() const { return String().Cat() << '(' << a << ", " << b << ", " << c << ", " << d << ')'; } + + template + operator Tuple4() const { Tuple4 t; t.a = (AA)a; t.b = (BB)b; t.c = (CC)c; t.d = (DD)d; return t; } }; template @@ -127,3 +136,45 @@ inline T *FindTuple(T *x, int n, const U& key) { } return NULL; } + +template +struct Tie2 { + A& a; + B& b; + + void operator=(const Tuple2& s) { a = s.a; b = s.b; } + + Tie2(A& a, B& b) : a(a), b(b) {} +}; + +template +Tie2 Tie(A& a, B& b) { return Tie2(a, b); } + +template +struct Tie3 { + A& a; + B& b; + C& c; + + void operator=(const Tuple3& s) { a = s.a; b = s.b; c = s.c; } + + Tie3(A& a, B& b, C& c) : a(a), b(b), c(c) {} +}; + +template +Tie3 Tie(A& a, B& b, C& c) { return Tie3(a, b, c); } + +template +struct Tie4 { + A& a; + B& b; + C& c; + D& d; + + void operator=(const Tuple4& s) { a = s.a; b = s.b; c = s.c; d = s.d; } + + Tie4(A& a, B& b, C& c, D& d) : a(a), b(b), c(c), d(d) {} +}; + +template +Tie4 Tie(A& a, B& b, C& c, D& d) { return Tie4(a, b, c, d); } diff --git a/uppsrc/Core/Value.cpp b/uppsrc/Core/Value.cpp index caa2450f0..e0499361f 100644 --- a/uppsrc/Core/Value.cpp +++ b/uppsrc/Core/Value.cpp @@ -90,6 +90,39 @@ bool Value::operator==(const Value& v) const { return svo[st]->IsEqual(&data, &v.data); } +int Value::PolyCompare(const Value& v) const +{ + int st = data.GetSpecial(); + if(st == REF) + return ptr()->PolyCompare(v); + if(st != VOIDV) + return svo[st]->PolyCompare(&data, v); + return 0; +} + +int Value::Compare(const Value& v) const +{ + if(IsString() && v.IsString()) + return SgnCompare(data, v.data); + bool a = IsNull(); + bool b = v.IsNull(); + if(a || b) + return SgnCompare(b, a); + int st = data.GetSpecial(); + if(GetType() == v.GetType()) { + if(st == REF) + return ptr()->Compare(v.ptr()); + if(st != VOIDV) + return svo[st]->Compare(&data, &v.data); + } + if(st != VOIDV) { + int q = PolyCompare(v); + if(q) return q; // Perhaps optimize this + return v.PolyCompare(*this); + } + return 0; +} + static bool sIsSame(const Value& a, const Value& b) { if(a.Is() && b.Is()) { diff --git a/uppsrc/Core/Value.h b/uppsrc/Core/Value.h index 6960d73c9..8f589cada 100644 --- a/uppsrc/Core/Value.h +++ b/uppsrc/Core/Value.h @@ -62,6 +62,8 @@ public: unsigned GetHashValue() const { return 0; } bool operator==(const T&) const { NEVER(); return false; } String ToString() const { return typeid(T).name(); } + int Compare(const T&) const { NEVER(); return 0; } + int PolyCompare(const Value&) const { NEVER(); return 0; } operator ValueTypeRef(); }; @@ -92,6 +94,8 @@ public: virtual bool IsEqual(const Void *p) { return false; } virtual bool IsPolyEqual(const Value& v) { return false; } virtual String AsString() const { return ""; } + virtual int Compare(const Void *p) { return 0; } + virtual int PolyCompare(const Value& p) { return 0; } Void() { refcount = 1; } virtual ~Void() {} @@ -108,6 +112,8 @@ public: bool (*IsEqual)(const void *p1, const void *p2); bool (*IsPolyEqual)(const void *p, const Value& v); String (*AsString)(const void *p); + int (*Compare)(const void *p1, const void *p2); + int (*PolyCompare)(const void *p1, const Value& p2); }; protected: @@ -164,6 +170,8 @@ protected: String GetName() const; + int PolyCompare(const Value& v) const; + #if defined(_DEBUG) && defined(COMPILER_GCC) uint32 magic[4]; void Magic() { magic[0] = 0xc436d851; magic[1] = 0x72f67c76; magic[2] = 0x3e5e10fd; magic[3] = 0xc90d370b; } @@ -216,6 +224,12 @@ public: bool operator==(const Value& v) const; bool operator!=(const Value& v) const { return !operator==(v); } bool IsSame(const Value& v) const; + + int Compare(const Value& v) const; + bool operator<=(const Value& x) const { return Compare(x) <= 0; } + bool operator>=(const Value& x) const { return Compare(x) >= 0; } + bool operator<(const Value& x) const { return Compare(x) < 0; } + bool operator>(const Value& x) const { return Compare(x) > 0; } String ToString() const; String GetTypeName() const { return GetName(); } @@ -250,7 +264,7 @@ template Value SvoToValue(const T& x) { return Value(x, Val template Value RichToValue(const T& data); template Value RawToValue(const T& data); -template Value RawPickToValue(pick_ T& data); +template Value RawPickToValue(T rval_ data); template Value RawDeepToValue(const T& data); template T& CreateRawValue(Value& v); diff --git a/uppsrc/Core/Value.hpp b/uppsrc/Core/Value.hpp index 0ac453762..c6decce6b 100644 --- a/uppsrc/Core/Value.hpp +++ b/uppsrc/Core/Value.hpp @@ -37,6 +37,57 @@ inline bool IsPolyEqual(const WString& x, const Value& v) { return v.GetType() == STRING_V && WString(v) == x; } +template +inline int PolyCompare(const T& a, const Value& b) +{ + return a.PolyCompare(b); +} + +template<> +inline int PolyCompare(const WString& x, const Value& v) { + return IsString(v) && SgnCompare(x, WString(v)); +} + +template<> +inline int PolyCompare(const String& x, const Value& v) { + return IsString(v) && SgnCompare((WString)x, (WString)v); +} + +template<> +inline int PolyCompare(const bool& x, const Value& v) { + return v.Is() ? SgnCompare((int64)x, (int64)v) + : IsNumber(v) ? SgnCompare((double)x, (double)v) + : 0; +} + +template<> +inline int PolyCompare(const int& x, const Value& v) { + return v.Is() ? SgnCompare((int64)x, (int64)v) + : IsNumber(v) ? SgnCompare((double)x, (double)v) + : 0; +} + +template<> +inline int PolyCompare(const int64& x, const Value& v) { + return v.Is() ? SgnCompare((double)x, (double)v) + : IsNumber(v) ? SgnCompare((int64)x, (int64)v) + : 0; +} + +inline int PolyCompare(const double& x, const Value& v) { + return IsNumber(v) ? SgnCompare((double)x, (double)v) : 0; +} + +template<> +inline int PolyCompare(const Date& x, const Value& v) { + return v.Is