From e87b4ac1dc33332210cab14a1f666a6bf7015efe Mon Sep 17 00:00:00 2001 From: Paul Richards Date: Mon, 2 Aug 1993 01:09:02 +0000 Subject: [PATCH] Added missing include files. --- gnu/lib/libg++/Makefile | 8 + gnu/lib/libg++/g++-include/AVLMap.ccP | 614 ++++++++++++ gnu/lib/libg++/g++-include/AVLMap.hP | 141 +++ gnu/lib/libg++/g++-include/AVLSet.ccP | 892 +++++++++++++++++ gnu/lib/libg++/g++-include/AVLSet.hP | 152 +++ gnu/lib/libg++/g++-include/AVec.ccP | 397 ++++++++ gnu/lib/libg++/g++-include/AVec.hP | 113 +++ gnu/lib/libg++/g++-include/BSTSet.ccP | 378 ++++++++ gnu/lib/libg++/g++-include/BSTSet.hP | 152 +++ gnu/lib/libg++/g++-include/Bag.ccP | 74 ++ gnu/lib/libg++/g++-include/Bag.hP | 79 ++ gnu/lib/libg++/g++-include/CHBag.ccP | 209 ++++ gnu/lib/libg++/g++-include/CHBag.hP | 76 ++ gnu/lib/libg++/g++-include/CHMap.ccP | 166 ++++ gnu/lib/libg++/g++-include/CHMap.hP | 104 ++ gnu/lib/libg++/g++-include/CHNode.ccP | 21 + gnu/lib/libg++/g++-include/CHNode.hP | 43 + gnu/lib/libg++/g++-include/CHSet.ccP | 271 ++++++ gnu/lib/libg++/g++-include/CHSet.hP | 84 ++ gnu/lib/libg++/g++-include/DLDeque.ccP | 4 + gnu/lib/libg++/g++-include/DLDeque.hP | 130 +++ gnu/lib/libg++/g++-include/DLList.ccP | 339 +++++++ gnu/lib/libg++/g++-include/DLList.hP | 157 +++ gnu/lib/libg++/g++-include/Deque.ccP | 11 + gnu/lib/libg++/g++-include/Deque.hP | 57 ++ gnu/lib/libg++/g++-include/FPQueue.ccP | 4 + gnu/lib/libg++/g++-include/FPQueue.hP | 112 +++ gnu/lib/libg++/g++-include/FPStack.ccP | 4 + gnu/lib/libg++/g++-include/FPStack.hP | 114 +++ gnu/lib/libg++/g++-include/FPlex.ccP | 167 ++++ gnu/lib/libg++/g++-include/FPlex.hP | 253 +++++ gnu/lib/libg++/g++-include/List.ccP | 956 +++++++++++++++++++ gnu/lib/libg++/g++-include/List.hP | 273 ++++++ gnu/lib/libg++/g++-include/MPlex.ccP | 845 ++++++++++++++++ gnu/lib/libg++/g++-include/MPlex.hP | 414 ++++++++ gnu/lib/libg++/g++-include/Map.ccP | 58 ++ gnu/lib/libg++/g++-include/Map.hP | 87 ++ gnu/lib/libg++/g++-include/OSLBag.ccP | 196 ++++ gnu/lib/libg++/g++-include/OSLBag.hP | 91 ++ gnu/lib/libg++/g++-include/OSLSet.ccP | 321 +++++++ gnu/lib/libg++/g++-include/OSLSet.hP | 101 ++ gnu/lib/libg++/g++-include/OXPBag.ccP | 221 +++++ gnu/lib/libg++/g++-include/OXPBag.hP | 73 ++ gnu/lib/libg++/g++-include/OXPSet.ccP | 280 ++++++ gnu/lib/libg++/g++-include/OXPSet.hP | 102 ++ gnu/lib/libg++/g++-include/PHPQ.ccP | 339 +++++++ gnu/lib/libg++/g++-include/PHPQ.hP | 108 +++ gnu/lib/libg++/g++-include/PQ.ccP | 62 ++ gnu/lib/libg++/g++-include/PQ.hP | 78 ++ gnu/lib/libg++/g++-include/PSList.hP | 32 + gnu/lib/libg++/g++-include/PVec.hP | 79 ++ gnu/lib/libg++/g++-include/Plex.ccP | 222 +++++ gnu/lib/libg++/g++-include/Plex.hP | 494 ++++++++++ gnu/lib/libg++/g++-include/Queue.ccP | 14 + gnu/lib/libg++/g++-include/Queue.hP | 51 + gnu/lib/libg++/g++-include/RAVLMap.ccP | 690 +++++++++++++ gnu/lib/libg++/g++-include/RAVLMap.hP | 147 +++ gnu/lib/libg++/g++-include/RPlex.ccP | 477 +++++++++ gnu/lib/libg++/g++-include/RPlex.hP | 257 +++++ gnu/lib/libg++/g++-include/SLBag.ccP | 105 ++ gnu/lib/libg++/g++-include/SLBag.hP | 96 ++ gnu/lib/libg++/g++-include/SLList.ccP | 292 ++++++ gnu/lib/libg++/g++-include/SLList.hP | 137 +++ gnu/lib/libg++/g++-include/SLQueue.ccP | 4 + gnu/lib/libg++/g++-include/SLQueue.hP | 108 +++ gnu/lib/libg++/g++-include/SLSet.ccP | 76 ++ gnu/lib/libg++/g++-include/SLSet.hP | 87 ++ gnu/lib/libg++/g++-include/SLStack.ccP | 4 + gnu/lib/libg++/g++-include/SLStack.hP | 109 +++ gnu/lib/libg++/g++-include/Set.ccP | 116 +++ gnu/lib/libg++/g++-include/Set.hP | 78 ++ gnu/lib/libg++/g++-include/SkipBag.ccP | 322 +++++++ gnu/lib/libg++/g++-include/SkipBag.hP | 171 ++++ gnu/lib/libg++/g++-include/SkipMap.ccP | 307 ++++++ gnu/lib/libg++/g++-include/SkipMap.hP | 176 ++++ gnu/lib/libg++/g++-include/SkipSet.ccP | 395 ++++++++ gnu/lib/libg++/g++-include/SkipSet.hP | 187 ++++ gnu/lib/libg++/g++-include/SplayBag.ccP | 445 +++++++++ gnu/lib/libg++/g++-include/SplayBag.hP | 144 +++ gnu/lib/libg++/g++-include/SplayMap.ccP | 401 ++++++++ gnu/lib/libg++/g++-include/SplayMap.hP | 154 +++ gnu/lib/libg++/g++-include/SplayNode.ccP | 21 + gnu/lib/libg++/g++-include/SplayNode.hP | 44 + gnu/lib/libg++/g++-include/SplayPQ.ccP | 523 ++++++++++ gnu/lib/libg++/g++-include/SplayPQ.hP | 123 +++ gnu/lib/libg++/g++-include/SplaySet.ccP | 499 ++++++++++ gnu/lib/libg++/g++-include/SplaySet.hP | 133 +++ gnu/lib/libg++/g++-include/Stack.ccP | 11 + gnu/lib/libg++/g++-include/Stack.hP | 51 + gnu/lib/libg++/g++-include/VHBag.ccP | 264 +++++ gnu/lib/libg++/g++-include/VHBag.hP | 84 ++ gnu/lib/libg++/g++-include/VHMap.ccP | 210 ++++ gnu/lib/libg++/g++-include/VHMap.hP | 84 ++ gnu/lib/libg++/g++-include/VHSet.ccP | 263 +++++ gnu/lib/libg++/g++-include/VHSet.hP | 96 ++ gnu/lib/libg++/g++-include/VOHSet.ccP | 308 ++++++ gnu/lib/libg++/g++-include/VOHSet.hP | 88 ++ gnu/lib/libg++/g++-include/VQueue.ccP | 83 ++ gnu/lib/libg++/g++-include/VQueue.hP | 130 +++ gnu/lib/libg++/g++-include/VStack.ccP | 66 ++ gnu/lib/libg++/g++-include/VStack.hP | 120 +++ gnu/lib/libg++/g++-include/Vec.ccP | 470 +++++++++ gnu/lib/libg++/g++-include/Vec.hP | 135 +++ gnu/lib/libg++/g++-include/XPBag.ccP | 72 ++ gnu/lib/libg++/g++-include/XPBag.hP | 98 ++ gnu/lib/libg++/g++-include/XPDeque.ccP | 4 + gnu/lib/libg++/g++-include/XPDeque.hP | 133 +++ gnu/lib/libg++/g++-include/XPPQ.ccP | 143 +++ gnu/lib/libg++/g++-include/XPPQ.hP | 105 ++ gnu/lib/libg++/g++-include/XPQueue.ccP | 4 + gnu/lib/libg++/g++-include/XPQueue.hP | 114 +++ gnu/lib/libg++/g++-include/XPSet.ccP | 63 ++ gnu/lib/libg++/g++-include/XPSet.hP | 89 ++ gnu/lib/libg++/g++-include/XPStack.ccP | 4 + gnu/lib/libg++/g++-include/XPStack.hP | 115 +++ gnu/lib/libg++/g++-include/XPlex.ccP | 397 ++++++++ gnu/lib/libg++/g++-include/XPlex.hP | 238 +++++ gnu/lib/libg++/g++-include/defs.hP | 57 ++ gnu/lib/libg++/g++-include/gen/AVLMap.ccP | 614 ++++++++++++ gnu/lib/libg++/g++-include/gen/AVLMap.hP | 141 +++ gnu/lib/libg++/g++-include/gen/AVLSet.ccP | 892 +++++++++++++++++ gnu/lib/libg++/g++-include/gen/AVLSet.hP | 152 +++ gnu/lib/libg++/g++-include/gen/AVec.ccP | 397 ++++++++ gnu/lib/libg++/g++-include/gen/AVec.hP | 113 +++ gnu/lib/libg++/g++-include/gen/BSTSet.ccP | 378 ++++++++ gnu/lib/libg++/g++-include/gen/BSTSet.hP | 152 +++ gnu/lib/libg++/g++-include/gen/Bag.ccP | 74 ++ gnu/lib/libg++/g++-include/gen/Bag.hP | 79 ++ gnu/lib/libg++/g++-include/gen/CHBag.ccP | 209 ++++ gnu/lib/libg++/g++-include/gen/CHBag.hP | 76 ++ gnu/lib/libg++/g++-include/gen/CHMap.ccP | 166 ++++ gnu/lib/libg++/g++-include/gen/CHMap.hP | 104 ++ gnu/lib/libg++/g++-include/gen/CHNode.ccP | 21 + gnu/lib/libg++/g++-include/gen/CHNode.hP | 43 + gnu/lib/libg++/g++-include/gen/CHSet.ccP | 271 ++++++ gnu/lib/libg++/g++-include/gen/CHSet.hP | 84 ++ gnu/lib/libg++/g++-include/gen/DLDeque.ccP | 4 + gnu/lib/libg++/g++-include/gen/DLDeque.hP | 130 +++ gnu/lib/libg++/g++-include/gen/DLList.ccP | 339 +++++++ gnu/lib/libg++/g++-include/gen/DLList.hP | 157 +++ gnu/lib/libg++/g++-include/gen/Deque.ccP | 11 + gnu/lib/libg++/g++-include/gen/Deque.hP | 57 ++ gnu/lib/libg++/g++-include/gen/FPQueue.ccP | 4 + gnu/lib/libg++/g++-include/gen/FPQueue.hP | 112 +++ gnu/lib/libg++/g++-include/gen/FPStack.ccP | 4 + gnu/lib/libg++/g++-include/gen/FPStack.hP | 114 +++ gnu/lib/libg++/g++-include/gen/FPlex.ccP | 167 ++++ gnu/lib/libg++/g++-include/gen/FPlex.hP | 253 +++++ gnu/lib/libg++/g++-include/gen/List.ccP | 956 +++++++++++++++++++ gnu/lib/libg++/g++-include/gen/List.hP | 273 ++++++ gnu/lib/libg++/g++-include/gen/MPlex.ccP | 845 ++++++++++++++++ gnu/lib/libg++/g++-include/gen/MPlex.hP | 414 ++++++++ gnu/lib/libg++/g++-include/gen/Map.ccP | 58 ++ gnu/lib/libg++/g++-include/gen/Map.hP | 87 ++ gnu/lib/libg++/g++-include/gen/OSLBag.ccP | 196 ++++ gnu/lib/libg++/g++-include/gen/OSLBag.hP | 91 ++ gnu/lib/libg++/g++-include/gen/OSLSet.ccP | 321 +++++++ gnu/lib/libg++/g++-include/gen/OSLSet.hP | 101 ++ gnu/lib/libg++/g++-include/gen/OXPBag.ccP | 221 +++++ gnu/lib/libg++/g++-include/gen/OXPBag.hP | 73 ++ gnu/lib/libg++/g++-include/gen/OXPSet.ccP | 280 ++++++ gnu/lib/libg++/g++-include/gen/OXPSet.hP | 102 ++ gnu/lib/libg++/g++-include/gen/PHPQ.ccP | 339 +++++++ gnu/lib/libg++/g++-include/gen/PHPQ.hP | 108 +++ gnu/lib/libg++/g++-include/gen/PQ.ccP | 62 ++ gnu/lib/libg++/g++-include/gen/PQ.hP | 78 ++ gnu/lib/libg++/g++-include/gen/PSList.hP | 32 + gnu/lib/libg++/g++-include/gen/PVec.hP | 79 ++ gnu/lib/libg++/g++-include/gen/Plex.ccP | 222 +++++ gnu/lib/libg++/g++-include/gen/Plex.hP | 494 ++++++++++ gnu/lib/libg++/g++-include/gen/Queue.ccP | 14 + gnu/lib/libg++/g++-include/gen/Queue.hP | 51 + gnu/lib/libg++/g++-include/gen/RAVLMap.ccP | 690 +++++++++++++ gnu/lib/libg++/g++-include/gen/RAVLMap.hP | 147 +++ gnu/lib/libg++/g++-include/gen/RPlex.ccP | 477 +++++++++ gnu/lib/libg++/g++-include/gen/RPlex.hP | 257 +++++ gnu/lib/libg++/g++-include/gen/SLBag.ccP | 105 ++ gnu/lib/libg++/g++-include/gen/SLBag.hP | 96 ++ gnu/lib/libg++/g++-include/gen/SLList.ccP | 292 ++++++ gnu/lib/libg++/g++-include/gen/SLList.hP | 137 +++ gnu/lib/libg++/g++-include/gen/SLQueue.ccP | 4 + gnu/lib/libg++/g++-include/gen/SLQueue.hP | 108 +++ gnu/lib/libg++/g++-include/gen/SLSet.ccP | 76 ++ gnu/lib/libg++/g++-include/gen/SLSet.hP | 87 ++ gnu/lib/libg++/g++-include/gen/SLStack.ccP | 4 + gnu/lib/libg++/g++-include/gen/SLStack.hP | 109 +++ gnu/lib/libg++/g++-include/gen/Set.ccP | 116 +++ gnu/lib/libg++/g++-include/gen/Set.hP | 78 ++ gnu/lib/libg++/g++-include/gen/SkipBag.ccP | 322 +++++++ gnu/lib/libg++/g++-include/gen/SkipBag.hP | 171 ++++ gnu/lib/libg++/g++-include/gen/SkipMap.ccP | 307 ++++++ gnu/lib/libg++/g++-include/gen/SkipMap.hP | 176 ++++ gnu/lib/libg++/g++-include/gen/SkipSet.ccP | 395 ++++++++ gnu/lib/libg++/g++-include/gen/SkipSet.hP | 187 ++++ gnu/lib/libg++/g++-include/gen/SplayBag.ccP | 445 +++++++++ gnu/lib/libg++/g++-include/gen/SplayBag.hP | 144 +++ gnu/lib/libg++/g++-include/gen/SplayMap.ccP | 401 ++++++++ gnu/lib/libg++/g++-include/gen/SplayMap.hP | 154 +++ gnu/lib/libg++/g++-include/gen/SplayNode.ccP | 21 + gnu/lib/libg++/g++-include/gen/SplayNode.hP | 44 + gnu/lib/libg++/g++-include/gen/SplayPQ.ccP | 523 ++++++++++ gnu/lib/libg++/g++-include/gen/SplayPQ.hP | 123 +++ gnu/lib/libg++/g++-include/gen/SplaySet.ccP | 499 ++++++++++ gnu/lib/libg++/g++-include/gen/SplaySet.hP | 133 +++ gnu/lib/libg++/g++-include/gen/Stack.ccP | 11 + gnu/lib/libg++/g++-include/gen/Stack.hP | 51 + gnu/lib/libg++/g++-include/gen/VHBag.ccP | 264 +++++ gnu/lib/libg++/g++-include/gen/VHBag.hP | 84 ++ gnu/lib/libg++/g++-include/gen/VHMap.ccP | 210 ++++ gnu/lib/libg++/g++-include/gen/VHMap.hP | 84 ++ gnu/lib/libg++/g++-include/gen/VHSet.ccP | 263 +++++ gnu/lib/libg++/g++-include/gen/VHSet.hP | 96 ++ gnu/lib/libg++/g++-include/gen/VOHSet.ccP | 308 ++++++ gnu/lib/libg++/g++-include/gen/VOHSet.hP | 88 ++ gnu/lib/libg++/g++-include/gen/VQueue.ccP | 83 ++ gnu/lib/libg++/g++-include/gen/VQueue.hP | 130 +++ gnu/lib/libg++/g++-include/gen/VStack.ccP | 66 ++ gnu/lib/libg++/g++-include/gen/VStack.hP | 120 +++ gnu/lib/libg++/g++-include/gen/Vec.ccP | 470 +++++++++ gnu/lib/libg++/g++-include/gen/Vec.hP | 135 +++ gnu/lib/libg++/g++-include/gen/XPBag.ccP | 72 ++ gnu/lib/libg++/g++-include/gen/XPBag.hP | 98 ++ gnu/lib/libg++/g++-include/gen/XPDeque.ccP | 4 + gnu/lib/libg++/g++-include/gen/XPDeque.hP | 133 +++ gnu/lib/libg++/g++-include/gen/XPPQ.ccP | 143 +++ gnu/lib/libg++/g++-include/gen/XPPQ.hP | 105 ++ gnu/lib/libg++/g++-include/gen/XPQueue.ccP | 4 + gnu/lib/libg++/g++-include/gen/XPQueue.hP | 114 +++ gnu/lib/libg++/g++-include/gen/XPSet.ccP | 63 ++ gnu/lib/libg++/g++-include/gen/XPSet.hP | 89 ++ gnu/lib/libg++/g++-include/gen/XPStack.ccP | 4 + gnu/lib/libg++/g++-include/gen/XPStack.hP | 115 +++ gnu/lib/libg++/g++-include/gen/XPlex.ccP | 397 ++++++++ gnu/lib/libg++/g++-include/gen/XPlex.hP | 238 +++++ gnu/lib/libg++/g++-include/gen/defs.hP | 57 ++ gnu/lib/libg++/g++-include/gen/intSList.hP | 33 + gnu/lib/libg++/g++-include/gen/intVec.hP | 80 ++ gnu/lib/libg++/g++-include/intSList.hP | 33 + gnu/lib/libg++/g++-include/intVec.hP | 80 ++ gnu/lib/libg++/libg++/Complex.h | 6 + gnu/lib/libg++/libg++/Incremental.h | 12 + gnu/lib/libg++/libg++/bool.h | 13 + gnu/lib/libg++/libg++/complex.h | 6 + gnu/lib/libg++/libg++/generic.h | 54 ++ gnu/lib/libg++/libg++/getpagesize.h | 27 + gnu/lib/libg++/libg++/libc.h | 1 + gnu/lib/libg++/libg++/math-68881.h | 516 ++++++++++ gnu/lib/libg++/libg++/minmax.h | 65 ++ gnu/lib/libg++/libg++/strclass.h | 5 + gnu/lib/libg++/libg++/swap.h | 3 + gnu/lib/libg++/libg++/typemacros.h | 8 + 251 files changed, 44434 insertions(+) create mode 100644 gnu/lib/libg++/g++-include/AVLMap.ccP create mode 100644 gnu/lib/libg++/g++-include/AVLMap.hP create mode 100644 gnu/lib/libg++/g++-include/AVLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/AVLSet.hP create mode 100644 gnu/lib/libg++/g++-include/AVec.ccP create mode 100644 gnu/lib/libg++/g++-include/AVec.hP create mode 100644 gnu/lib/libg++/g++-include/BSTSet.ccP create mode 100644 gnu/lib/libg++/g++-include/BSTSet.hP create mode 100644 gnu/lib/libg++/g++-include/Bag.ccP create mode 100644 gnu/lib/libg++/g++-include/Bag.hP create mode 100644 gnu/lib/libg++/g++-include/CHBag.ccP create mode 100644 gnu/lib/libg++/g++-include/CHBag.hP create mode 100644 gnu/lib/libg++/g++-include/CHMap.ccP create mode 100644 gnu/lib/libg++/g++-include/CHMap.hP create mode 100644 gnu/lib/libg++/g++-include/CHNode.ccP create mode 100644 gnu/lib/libg++/g++-include/CHNode.hP create mode 100644 gnu/lib/libg++/g++-include/CHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/CHSet.hP create mode 100644 gnu/lib/libg++/g++-include/DLDeque.ccP create mode 100644 gnu/lib/libg++/g++-include/DLDeque.hP create mode 100644 gnu/lib/libg++/g++-include/DLList.ccP create mode 100644 gnu/lib/libg++/g++-include/DLList.hP create mode 100644 gnu/lib/libg++/g++-include/Deque.ccP create mode 100644 gnu/lib/libg++/g++-include/Deque.hP create mode 100644 gnu/lib/libg++/g++-include/FPQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/FPQueue.hP create mode 100644 gnu/lib/libg++/g++-include/FPStack.ccP create mode 100644 gnu/lib/libg++/g++-include/FPStack.hP create mode 100644 gnu/lib/libg++/g++-include/FPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/FPlex.hP create mode 100644 gnu/lib/libg++/g++-include/List.ccP create mode 100644 gnu/lib/libg++/g++-include/List.hP create mode 100644 gnu/lib/libg++/g++-include/MPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/MPlex.hP create mode 100644 gnu/lib/libg++/g++-include/Map.ccP create mode 100644 gnu/lib/libg++/g++-include/Map.hP create mode 100644 gnu/lib/libg++/g++-include/OSLBag.ccP create mode 100644 gnu/lib/libg++/g++-include/OSLBag.hP create mode 100644 gnu/lib/libg++/g++-include/OSLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/OSLSet.hP create mode 100644 gnu/lib/libg++/g++-include/OXPBag.ccP create mode 100644 gnu/lib/libg++/g++-include/OXPBag.hP create mode 100644 gnu/lib/libg++/g++-include/OXPSet.ccP create mode 100644 gnu/lib/libg++/g++-include/OXPSet.hP create mode 100644 gnu/lib/libg++/g++-include/PHPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/PHPQ.hP create mode 100644 gnu/lib/libg++/g++-include/PQ.ccP create mode 100644 gnu/lib/libg++/g++-include/PQ.hP create mode 100644 gnu/lib/libg++/g++-include/PSList.hP create mode 100644 gnu/lib/libg++/g++-include/PVec.hP create mode 100644 gnu/lib/libg++/g++-include/Plex.ccP create mode 100644 gnu/lib/libg++/g++-include/Plex.hP create mode 100644 gnu/lib/libg++/g++-include/Queue.ccP create mode 100644 gnu/lib/libg++/g++-include/Queue.hP create mode 100644 gnu/lib/libg++/g++-include/RAVLMap.ccP create mode 100644 gnu/lib/libg++/g++-include/RAVLMap.hP create mode 100644 gnu/lib/libg++/g++-include/RPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/RPlex.hP create mode 100644 gnu/lib/libg++/g++-include/SLBag.ccP create mode 100644 gnu/lib/libg++/g++-include/SLBag.hP create mode 100644 gnu/lib/libg++/g++-include/SLList.ccP create mode 100644 gnu/lib/libg++/g++-include/SLList.hP create mode 100644 gnu/lib/libg++/g++-include/SLQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/SLQueue.hP create mode 100644 gnu/lib/libg++/g++-include/SLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/SLSet.hP create mode 100644 gnu/lib/libg++/g++-include/SLStack.ccP create mode 100644 gnu/lib/libg++/g++-include/SLStack.hP create mode 100644 gnu/lib/libg++/g++-include/Set.ccP create mode 100644 gnu/lib/libg++/g++-include/Set.hP create mode 100644 gnu/lib/libg++/g++-include/SkipBag.ccP create mode 100644 gnu/lib/libg++/g++-include/SkipBag.hP create mode 100644 gnu/lib/libg++/g++-include/SkipMap.ccP create mode 100644 gnu/lib/libg++/g++-include/SkipMap.hP create mode 100644 gnu/lib/libg++/g++-include/SkipSet.ccP create mode 100644 gnu/lib/libg++/g++-include/SkipSet.hP create mode 100644 gnu/lib/libg++/g++-include/SplayBag.ccP create mode 100644 gnu/lib/libg++/g++-include/SplayBag.hP create mode 100644 gnu/lib/libg++/g++-include/SplayMap.ccP create mode 100644 gnu/lib/libg++/g++-include/SplayMap.hP create mode 100644 gnu/lib/libg++/g++-include/SplayNode.ccP create mode 100644 gnu/lib/libg++/g++-include/SplayNode.hP create mode 100644 gnu/lib/libg++/g++-include/SplayPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/SplayPQ.hP create mode 100644 gnu/lib/libg++/g++-include/SplaySet.ccP create mode 100644 gnu/lib/libg++/g++-include/SplaySet.hP create mode 100644 gnu/lib/libg++/g++-include/Stack.ccP create mode 100644 gnu/lib/libg++/g++-include/Stack.hP create mode 100644 gnu/lib/libg++/g++-include/VHBag.ccP create mode 100644 gnu/lib/libg++/g++-include/VHBag.hP create mode 100644 gnu/lib/libg++/g++-include/VHMap.ccP create mode 100644 gnu/lib/libg++/g++-include/VHMap.hP create mode 100644 gnu/lib/libg++/g++-include/VHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/VHSet.hP create mode 100644 gnu/lib/libg++/g++-include/VOHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/VOHSet.hP create mode 100644 gnu/lib/libg++/g++-include/VQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/VQueue.hP create mode 100644 gnu/lib/libg++/g++-include/VStack.ccP create mode 100644 gnu/lib/libg++/g++-include/VStack.hP create mode 100644 gnu/lib/libg++/g++-include/Vec.ccP create mode 100644 gnu/lib/libg++/g++-include/Vec.hP create mode 100644 gnu/lib/libg++/g++-include/XPBag.ccP create mode 100644 gnu/lib/libg++/g++-include/XPBag.hP create mode 100644 gnu/lib/libg++/g++-include/XPDeque.ccP create mode 100644 gnu/lib/libg++/g++-include/XPDeque.hP create mode 100644 gnu/lib/libg++/g++-include/XPPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/XPPQ.hP create mode 100644 gnu/lib/libg++/g++-include/XPQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/XPQueue.hP create mode 100644 gnu/lib/libg++/g++-include/XPSet.ccP create mode 100644 gnu/lib/libg++/g++-include/XPSet.hP create mode 100644 gnu/lib/libg++/g++-include/XPStack.ccP create mode 100644 gnu/lib/libg++/g++-include/XPStack.hP create mode 100644 gnu/lib/libg++/g++-include/XPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/XPlex.hP create mode 100644 gnu/lib/libg++/g++-include/defs.hP create mode 100644 gnu/lib/libg++/g++-include/gen/AVLMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/AVLMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/AVLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/AVLSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/AVec.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/AVec.hP create mode 100644 gnu/lib/libg++/g++-include/gen/BSTSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/BSTSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Bag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Bag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/CHBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/CHBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/CHMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/CHMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/CHNode.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/CHNode.hP create mode 100644 gnu/lib/libg++/g++-include/gen/CHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/CHSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/DLDeque.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/DLDeque.hP create mode 100644 gnu/lib/libg++/g++-include/gen/DLList.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/DLList.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Deque.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Deque.hP create mode 100644 gnu/lib/libg++/g++-include/gen/FPQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/FPQueue.hP create mode 100644 gnu/lib/libg++/g++-include/gen/FPStack.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/FPStack.hP create mode 100644 gnu/lib/libg++/g++-include/gen/FPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/FPlex.hP create mode 100644 gnu/lib/libg++/g++-include/gen/List.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/List.hP create mode 100644 gnu/lib/libg++/g++-include/gen/MPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/MPlex.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Map.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Map.hP create mode 100644 gnu/lib/libg++/g++-include/gen/OSLBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/OSLBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/OSLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/OSLSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/OXPBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/OXPBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/OXPSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/OXPSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/PHPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/PHPQ.hP create mode 100644 gnu/lib/libg++/g++-include/gen/PQ.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/PQ.hP create mode 100644 gnu/lib/libg++/g++-include/gen/PSList.hP create mode 100644 gnu/lib/libg++/g++-include/gen/PVec.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Plex.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Plex.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Queue.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Queue.hP create mode 100644 gnu/lib/libg++/g++-include/gen/RAVLMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/RAVLMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/RPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/RPlex.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SLBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SLBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SLList.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SLList.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SLQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SLQueue.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SLSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SLSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SLStack.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SLStack.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Set.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Set.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SkipSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayNode.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayNode.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SplayPQ.hP create mode 100644 gnu/lib/libg++/g++-include/gen/SplaySet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/SplaySet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Stack.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Stack.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VHBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VHBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VHMap.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VHMap.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VHSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VOHSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VOHSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VQueue.hP create mode 100644 gnu/lib/libg++/g++-include/gen/VStack.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/VStack.hP create mode 100644 gnu/lib/libg++/g++-include/gen/Vec.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/Vec.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPBag.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPBag.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPDeque.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPDeque.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPPQ.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPPQ.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPQueue.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPQueue.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPSet.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPSet.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPStack.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPStack.hP create mode 100644 gnu/lib/libg++/g++-include/gen/XPlex.ccP create mode 100644 gnu/lib/libg++/g++-include/gen/XPlex.hP create mode 100644 gnu/lib/libg++/g++-include/gen/defs.hP create mode 100644 gnu/lib/libg++/g++-include/gen/intSList.hP create mode 100644 gnu/lib/libg++/g++-include/gen/intVec.hP create mode 100644 gnu/lib/libg++/g++-include/intSList.hP create mode 100644 gnu/lib/libg++/g++-include/intVec.hP create mode 100644 gnu/lib/libg++/libg++/Incremental.h create mode 100644 gnu/lib/libg++/libg++/bool.h create mode 100644 gnu/lib/libg++/libg++/complex.h create mode 100644 gnu/lib/libg++/libg++/generic.h create mode 100644 gnu/lib/libg++/libg++/getpagesize.h create mode 100644 gnu/lib/libg++/libg++/libc.h create mode 100644 gnu/lib/libg++/libg++/math-68881.h create mode 100644 gnu/lib/libg++/libg++/minmax.h create mode 100644 gnu/lib/libg++/libg++/strclass.h create mode 100644 gnu/lib/libg++/libg++/swap.h create mode 100644 gnu/lib/libg++/libg++/typemacros.h diff --git a/gnu/lib/libg++/Makefile b/gnu/lib/libg++/Makefile index a16401e834..0d27cdee98 100644 --- a/gnu/lib/libg++/Makefile +++ b/gnu/lib/libg++/Makefile @@ -6,6 +6,9 @@ beforeinstall: @-if [ ! -d ${DESTDIR}/usr/include/g++ ]; then \ mkdir ${DESTDIR}/usr/include/g++; \ fi + @-if [ ! -d ${DESTDIR}/usr/include/g++/gen ]; then \ + mkdir ${DESTDIR}/usr/include/g++/gen; \ + fi @-if [ ! -d ${DESTDIR}/usr/include/g++/sys ]; then \ mkdir ${DESTDIR}/usr/include/g++/sys; \ fi @@ -21,5 +24,10 @@ beforeinstall: cmp -s $$j ${DESTDIR}/usr/include/g++/sys/$$j || \ install -c -m 644 $$j ${DESTDIR}/usr/include/g++/sys/$$j; \ done) + @echo installing includes from g++-include/gen + @(cd g++-include/gen ; for j in *.P; do \ + cmp -s $$j ${DESTDIR}/usr/include/g++/gen/$$j || \ + install -c -m 644 $$j ${DESTDIR}/usr/include/g++/gen/$$j; \ + done) .include diff --git a/gnu/lib/libg++/g++-include/AVLMap.ccP b/gnu/lib/libg++/g++-include/AVLMap.ccP new file mode 100644 index 0000000000..a9be60f066 --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVLMap.ccP @@ -0,0 +1,614 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..AVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +AVLNode* AVLMap::leftmost() +{ + AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +AVLNode* AVLMap::rightmost() +{ + AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +AVLNode* AVLMap::succ(AVLNode* t) +{ + AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +AVLNode* AVLMap::pred(AVLNode* t) +{ + AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix AVLMap::seek( key) +{ + AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + + +void AVLMap:: _add(AVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +& AVLMap::operator [] ( item) +{ + if (root == 0) + { + ++count; + root = new AVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return _found_node->cont; + } +} + + +void AVLMap::_del(AVLNode* par, AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + AVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void AVLMap::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void AVLMap::_kill(AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +AVLMap::AVLMap(AVLMap& b) :Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int AVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + AVLNode* trail = leftmost(); + AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/AVLMap.hP b/gnu/lib/libg++/g++-include/AVLMap.hP new file mode 100644 index 0000000000..119ee82caa --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVLMap.hP @@ -0,0 +1,141 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVLMap_h 1 + +#include "..Map.h" + +struct AVLNode +{ + AVLNode* lt; + AVLNode* rt; + item; + cont; + char stat; + AVLNode( h, c, + AVLNode* l=0, AVLNode* r=0); + ~AVLNode(); +}; + +inline AVLNode::AVLNode( h, c, + AVLNode* l, AVLNode* r) + :item(h), cont(c), lt(l), rt(r), stat(0) {} + +inline AVLNode::~AVLNode() {} + +typedef AVLNode* AVLNodePtr; + + +class AVLMap : public Map +{ +protected: + AVLNode* root; + + AVLNode* leftmost(); + AVLNode* rightmost(); + AVLNode* pred(AVLNode* t); + AVLNode* succ(AVLNode* t); + void _kill(AVLNode* t); + void _add(AVLNode*& t); + void _del(AVLNode* p, AVLNode*& t); + +public: + AVLMap( dflt); + AVLMap(AVLMap& a); + ~AVLMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline AVLMap::~AVLMap() +{ + _kill(root); +} + +inline AVLMap::AVLMap( dflt) :Map(dflt) +{ + root = 0; +} + +inline Pix AVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix AVLMap::last() +{ + return Pix(rightmost()); +} + +inline void AVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((AVLNode*)i)); +} + +inline void AVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((AVLNode*)i)); +} + +inline & AVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->item; +} + +inline & AVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->cont; +} + +inline void AVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int AVLMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/AVLSet.ccP b/gnu/lib/libg++/g++-include/AVLSet.ccP new file mode 100644 index 0000000000..b170734e54 --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVLSet.ccP @@ -0,0 +1,892 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".AVLSet.h" +#include + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +AVLNode* AVLSet::leftmost() +{ + AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +AVLNode* AVLSet::rightmost() +{ + AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +AVLNode* AVLSet::succ(AVLNode* t) +{ + AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +AVLNode* AVLSet::pred(AVLNode* t) +{ + AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix AVLSet::seek( key) +{ + AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + +static AVLNode** _hold_nodes; // used for rebuilding trees +static int _max_hold_index; // # elements-1 in _hold_nodes + + +void AVLSet:: _add(AVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +Pix AVLSet::add( item) +{ + if (root == 0) + { + ++count; + root = new AVLNode(item); + set_rthread(root, 1); + set_lthread(root, 1); + return Pix(root); + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return Pix(_found_node); + } +} + + +void AVLSet::_del(AVLNode* par, AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + AVLNode* p = pred(t); + t->item = p->item; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void AVLSet::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +// build an ordered array of pointers to tree nodes back into a tree +// we know that at least one element exists + +static AVLNode* _do_treeify(int lo, int hi, int& h) +{ + int lh, rh; + int mid = (lo + hi) / 2; + AVLNode* t = _hold_nodes[mid]; + if (lo > mid - 1) + { + set_lthread(t, 1); + if (mid == 0) + t->lt = 0; + else + t->lt = _hold_nodes[mid-1]; + lh = 0; + } + else + { + set_lthread(t, 0); + t->lt = _do_treeify(lo, mid-1, lh); + } + if (hi < mid + 1) + { + set_rthread(t, 1); + if (mid == _max_hold_index) + t->rt = 0; + else + t->rt = _hold_nodes[mid+1]; + rh = 0; + } + else + { + set_rthread(t, 0); + t->rt = _do_treeify(mid+1, hi, rh); + } + if (lh == rh) + { + set_bf(t, AVLBALANCED); + h = lh + 1; + } + else if (lh == rh - 1) + { + set_bf(t, AVLRIGHTHEAVY); + h = rh + 1; + } + else if (rh == lh - 1) + { + set_bf(t, AVLLEFTHEAVY); + h = lh + 1; + } + else // can't happen + abort(); + + return t; +} + +static AVLNode* _treeify(int n) +{ + AVLNode* t; + if (n == 0) + t = 0; + else + { + int b; + _max_hold_index = n-1; + t = _do_treeify(0, _max_hold_index, b); + } + delete _hold_nodes; + return t; +} + + +void AVLSet::_kill(AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +AVLSet::AVLSet(AVLSet& b) +{ + if ((count = b.count) == 0) + { + root = 0; + } + else + { + _hold_nodes = new AVLNodePtr [count]; + AVLNode* t = b.leftmost(); + int i = 0; + while (t != 0) + { + _hold_nodes[i++] = new AVLNode(t->item); + t = b.succ(t); + } + root = _treeify(count); + } +} + + +int AVLSet::operator == (AVLSet& y) +{ + if (count != y.count) + return 0; + else + { + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!(EQ(t->item, u->item))) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int AVLSet::operator <= (AVLSet& y) +{ + if (count > y.count) + return 0; + else + { + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + +void AVLSet::operator |=(AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = count + y.count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + { + while (u != 0) + { + _hold_nodes[k++] = new AVLNode(u->item); + u = y.succ(u); + } + break; + } + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + { + _hold_nodes[k++] = new AVLNode(u->item); + u = y.succ(u); + } + } + root = _treeify(k); + count = k; +} + +void AVLSet::operator &= (AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = (count < y.count)? count : y.count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + if (u == 0) + { + while (t != 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + + +void AVLSet::operator -=(AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + +int AVLSet::owns(Pix i) +{ + if (i == 0) return 0; + for (AVLNode* t = leftmost(); t != 0; t = succ(t)) + if (Pix(t) == i) return 1; + return 0; +} + +int AVLSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + AVLNode* trail = leftmost(); + AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/AVLSet.hP b/gnu/lib/libg++/g++-include/AVLSet.hP new file mode 100644 index 0000000000..16ad1d1946 --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVLSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVL_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVL_h 1 + +#include ".Set.h" + +struct AVLNode +{ + AVLNode* lt; + AVLNode* rt; + item; + char stat; + AVLNode( h, AVLNode* l=0, AVLNode* r=0); + ~AVLNode(); +}; + +inline AVLNode::AVLNode( h, AVLNode* l, AVLNode* r) +:item(h), lt(l), rt(r), stat(0) {} + +inline AVLNode::~AVLNode() {} + +typedef AVLNode* AVLNodePtr; + + +class AVLSet : public Set +{ +protected: + AVLNode* root; + + AVLSet(AVLNode* p, int l); + + AVLNode* leftmost(); + AVLNode* rightmost(); + AVLNode* pred(AVLNode* t); + AVLNode* succ(AVLNode* t); + void _kill(AVLNode* t); + void _add(AVLNode*& t); + void _del(AVLNode* p, AVLNode*& t); + +public: + AVLSet(); + AVLSet(AVLSet& a); + ~AVLSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + void operator |= (AVLSet& b); + void operator -= (AVLSet& b); + void operator &= (AVLSet& b); + + int operator == (AVLSet& b); + int operator != (AVLSet& b); + int operator <= (AVLSet& b); + + int OK(); +}; + +inline AVLSet::~AVLSet() +{ + _kill(root); +} + +inline AVLSet::AVLSet() +{ + root = 0; + count = 0; +} + +inline AVLSet::AVLSet(AVLNode* p, int l) +{ + root = p; + count = l; +} + +inline int AVLSet::operator != (AVLSet& b) +{ + return ! ((*this) == b); +} + +inline Pix AVLSet::first() +{ + return Pix(leftmost()); +} + +inline Pix AVLSet::last() +{ + return Pix(rightmost()); +} + +inline void AVLSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((AVLNode*)i)); +} + +inline void AVLSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((AVLNode*)i)); +} + +inline & AVLSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->item; +} + +inline void AVLSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int AVLSet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/AVec.ccP b/gnu/lib/libg++/g++-include/AVec.ccP new file mode 100644 index 0000000000..bc671bf8e1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVec.ccP @@ -0,0 +1,397 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".AVec.h" + +/* + The following brought to you by the department of redundancy department +*/ + +AVec& AVec::operator = (AVec& v) +{ + if (len != 0 && len != v.capacity()) + error("nonconformant vectors."); + if (len == 0) + s = new [len = v.capacity()]; + if (s != v.vec()) + { + for (int i = 0; i < len; ++i) + s[i] = v.vec()[i]; + } + return *this; +} + +AVec& AVec::operator = ( f) +{ + for (int i = 0; i < len; ++i) s[i] = f; + return *this; +} + + +AVec concat(AVec & a, AVec & b) +{ + int newl = a.capacity() + b.capacity(); + * news = new [newl]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++; + top = &(b.vec()[b.capacity()]); + t = b.vec(); + while (t < top) *p++ = *t++; + return AVec(newl, news); +} + + +AVec combine(Combiner f, AVec& a, AVec& b) +{ + int newl = (a.capacity() < b.capacity())? a.capacity() : b.capacity(); + * news = new [newl]; + * p = news; + * top = &(a.vec()[newl]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = (*f)(*t++, *u++); + return AVec(newl, news); +} + +AVec reverse(AVec& a) +{ + * news = new [a.capacity()]; + if (a.capacity() != 0) + { + * lo = news; + * hi = &(news[a.capacity() - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } + return AVec(a.capacity(), news); +} + +AVec map(Mapper f, AVec& a) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while(t < top) *p++ = (*f)(*t++); + return AVec(a.capacity(), news); +} + +AVec AVec::at(int from, int n) +{ + int to; + if (n < 0) + { + n = len - from; + to = len - 1; + } + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * news = new [n]; + * p = news; + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *p++ = *t++; + return AVec(n, news); +} + +AVec merge(AVec & a, AVec & b, Comparator f) +{ + int newl = a.capacity() + b.capacity(); + * news = new [newl]; + * p = news; + * topa = &(a.vec()[a.capacity()]); + * as = a.vec(); + * topb = &(b.vec()[b.capacity()]); + * bs = b.vec(); + + for (;;) + { + if (as >= topa) + { + while (bs < topb) *p++ = *bs++; + break; + } + else if (bs >= topb) + { + while (as < topa) *p++ = *as++; + break; + } + else if ((*f)(*as, *bs) <= 0) + *p++ = *as++; + else + *p++ = *bs++; + } + return AVec(newl, news); +} + +AVec operator + (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ + *u++; + return AVec(a.capacity(), news); +} + +AVec operator - (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ - *u++; + return AVec(a.capacity(), news); +} + +AVec product (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ * *u++; + return AVec(a.capacity(), news); +} + +AVec quotient(AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ / *u++; + return AVec(a.capacity(), news); +} + +AVec operator + (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ + b; + return AVec(a.capacity(), news); +} + +AVec operator - (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ - b; + return AVec(a.capacity(), news); +} + +AVec operator * (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ * b; + return AVec(a.capacity(), news); +} + +AVec operator / (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ / b; + return AVec(a.capacity(), news); +} + +AVec AVec::operator - () +{ + * news = new [len]; + * p = news; + * top = &(s[len]); + * t = s; + while (t < top) *p++ = -(*t++); + return AVec(len, news); +} + +AVec& AVec::operator += (AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ += *u++; + return *this; +} + +AVec& AVec::operator -= (AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ -= *u++; + return *this; +} + +AVec& AVec::product(AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ *= *u++; + return *this; +} + +AVec& AVec::quotient(AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ /= *u++; + return *this; +} + +AVec& AVec::operator += ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ += b; + return *this; +} + +AVec& AVec::operator -= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ -= b; + return *this; +} + +AVec& AVec::operator *= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ *= b; + return *this; +} + +AVec& AVec::operator /= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ /= b; + return *this; +} + + AVec::max() +{ + if (len == 0) + return 0; + * top = &(s[len]); + * t = s; + res = *t++; + for (; t < top; ++t) if (*t > res) res = *t; + return res; +} + +int AVec::max_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] > s[ind]) + ind = i; + return ind; +} + + AVec::min() +{ + if (len == 0) + return 0; + * top = &(s[len]); + * t = s; + res = *t++; + for (; t < top; ++t) if (*t < res) res = *t; + return res; +} + +int AVec::min_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] < s[ind]) + ind = i; + return ind; +} + + AVec::sum() +{ + res = 0; + * top = &(s[len]); + * t = s; + while (t < top) res += *t++; + return res; +} + + + AVec::sumsq() +{ + res = 0; + * top = &(s[len]); + * t = s; + for (; t < top; ++t) res += *t * *t; + return res; +} + + operator * (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + res = 0; + while (t < top) res += *t++ * *u++; + return res; +} diff --git a/gnu/lib/libg++/g++-include/AVec.hP b/gnu/lib/libg++/g++-include/AVec.hP new file mode 100644 index 0000000000..cd9a9c3fe5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/AVec.hP @@ -0,0 +1,113 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVec_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVec_h 1 + +#include ".Vec.h" + +class AVec : public Vec +{ +protected: + void check_len(int l); + * vec(); + AVec(int l, * d); + public: + AVec (); + AVec (int l); + AVec (int l, fill_value); + AVec (AVec&); + ~AVec (); + + AVec& operator = (AVec& a); + AVec& operator = ( fill_value); + +// vector by scalar -> vector operations + + friend AVec operator + (AVec& a, b); + friend AVec operator - (AVec& a, b); + friend AVec operator * (AVec& a, b); + friend AVec operator / (AVec& a, b); + + AVec& operator += ( b); + AVec& operator -= ( b); + AVec& operator *= ( b); + AVec& operator /= ( b); + +// vector by vector -> vector operations + + friend AVec operator + (AVec& a, AVec& b); + friend AVec operator - (AVec& a, AVec& b); + AVec& operator += (AVec& b); + AVec& operator -= (AVec& b); + + AVec operator - (); + + friend AVec product(AVec& a, AVec& b); + AVec& product(AVec& b); + friend AVec quotient(AVec& a, AVec& b); + AVec& quotient(AVec& b); + +// vector -> scalar operations + + friend operator * (AVec& a, AVec& b); + + sum(); + min(); + max(); + sumsq(); + +// indexing + + int min_index(); + int max_index(); + +// redundant but necesssary + friend AVec concat(AVec& a, AVec& b); + friend AVec map(Mapper f, AVec& a); + friend AVec merge(AVec& a, AVec& b, Comparator f); + friend AVec combine(Combiner f, AVec& a, AVec& b); + friend AVec reverse(AVec& a); + AVec at(int from = 0, int n = -1); +}; + +inline AVec::AVec() {} +inline AVec::AVec(int l) :Vec(l) {} +inline AVec::AVec(int l, fill_value) : Vec (l, fill_value) {} +inline AVec::AVec(AVec& v) :Vec(v) {} +inline AVec::AVec(int l, * d) :Vec(l, d) {} +inline AVec::~AVec() {} + + +inline * AVec::vec() +{ + return s; +} + + +inline void AVec::check_len(int l) +{ + if (l != len) + error("nonconformant vectors."); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/BSTSet.ccP b/gnu/lib/libg++/g++-include/BSTSet.ccP new file mode 100644 index 0000000000..6a69d8f45b --- /dev/null +++ b/gnu/lib/libg++/g++-include/BSTSet.ccP @@ -0,0 +1,378 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".BSTSet.h" + + +/* + traversal primitives +*/ + + +BSTNode* BSTSet::leftmost() +{ + BSTNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +BSTNode* BSTSet::rightmost() +{ + BSTNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +BSTNode* BSTSet::succ(BSTNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +BSTNode* BSTSet::pred(BSTNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix BSTSet::seek( key) +{ + BSTNode* t = root; + for (;;) + { + if (t == 0) + return 0; + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + else if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +Pix BSTSet::add( item) +{ + if (root == 0) + { + ++count; + root = new BSTNode(item); + return Pix(root); + } + + BSTNode* t = root; + BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + { + ++count; + t = new BSTNode(item); + if (comp > 0) + p->lt = t; + else + p->rt = t; + t->par = p; + return Pix(t); + } + p = t; + comp = CMP(t->item, item); + if (comp == 0) + return Pix(t); + else if (comp > 0) + t = t->lt; + else + t = t->rt; + } +} + + +void BSTSet::del( key) +{ + BSTNode* t = root; + BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + return; + comp = CMP(key, t->item); + if (comp == 0) + { + --count; + BSTNode* repl; + if (t->lt == 0) + repl = t->rt; + else if (t->rt == 0) + repl = t->lt; + else + { + BSTNode* prepl = t; + repl = t->lt; + while (repl->rt != 0) + { + prepl = repl; + repl = repl->rt; + } + if (prepl != t) + { + prepl->rt = repl->lt; + if (prepl->rt != 0) prepl->rt->par = prepl; + repl->lt = t->lt; + if (repl->lt != 0) repl->lt->par = repl; + } + repl->rt = t->rt; + if (repl->rt != 0) repl->rt->par = repl; + } + if (t == root) + { + root = repl; + if (repl != 0) repl->par = 0; + } + else + { + if (t == p->lt) + p->lt = repl; + else + p->rt = repl; + if (repl != 0) repl->par = p; + } + delete t; + return; + } + p = t; + if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +void BSTSet::_kill(BSTNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + +BSTNode* BSTSet::_copy(BSTNode* t) +{ + if (t == 0) + return 0; + else + { + BSTNode* u = new BSTNode(t->item, _copy(t->lt), _copy(t->rt)); + if (u->lt != 0) u->lt->par = u; + if (u->rt != 0) u->rt->par = u; + return u; + } +} + + +int BSTSet::operator == (BSTSet& y) +{ + if (count != y.count) + return 0; + else + { + BSTNode* t = leftmost(); + BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int BSTSet::operator <= (BSTSet& y) +{ + if (count > y.count) + return 0; + else + { + BSTNode* t = leftmost(); + BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +// linear-time, zero space overhead binary tree rebalancing from +// Stout & Warren, ``Tree rebalancing in linear space and time'' +// CACM, Sept, 1986, p902. + + +void BSTSet::balance() +{ + if (count <= 2) return; // don't bother -- + // also we assume non-null root, below + + // make re-attaching the root easy via trickery + + struct _fake_node { _fake_node *lt, *rt, *par; } fake_root; + + fake_root.rt = (_fake_node*)root; + fake_root.par = 0; + BSTNode* pseudo_root = (BSTNode*)&fake_root; + + // phase 1: tree-to-vine + + BSTNode* vine_tail = pseudo_root; + BSTNode* remainder = root; + + while (remainder != 0) + { + if (remainder->lt == 0) + { + vine_tail = remainder; + remainder = remainder->rt; + } + else + { + BSTNode* tmp = remainder->lt; + remainder->lt = tmp->rt; + if (remainder->lt != 0) remainder->lt->par = remainder; + tmp->rt = remainder; + remainder->par = tmp; + vine_tail->rt = remainder = tmp; + } + } + + // phase 2: vine-to-tree + + // Uses the slightly simpler version adapted from + // Day ``Balancing a binary tree'' Computer Journal, Nov. 1976, + // since it's not generally important whether the `stray' leaves are + // on the left or on the right. + + unsigned int spines = count - 1; + while (spines > 1) + { + int compressions = spines >> 1; // compress every other node + spines -= compressions + 1; // halve for next time + + BSTNode* scanner = pseudo_root; + while (compressions-- > 0) + { + BSTNode* child = scanner->rt; + BSTNode* grandchild = child->rt; + scanner->rt = grandchild; + grandchild->par = scanner; + child->rt = grandchild->lt; + if (child->rt != 0) child->rt->par = child; + grandchild->lt = child; + child->par = grandchild; + scanner = grandchild; + } + } + + root = pseudo_root->rt; + root->par = 0; +} + + +int BSTSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + BSTNode* trail = leftmost(); + BSTNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/BSTSet.hP b/gnu/lib/libg++/g++-include/BSTSet.hP new file mode 100644 index 0000000000..82f2069c0f --- /dev/null +++ b/gnu/lib/libg++/g++-include/BSTSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _BSTSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _BSTSet_h 1 + +#include ".Set.h" + +#ifndef _BSTNode +#define _BSTNode 1 + +struct BSTNode +{ + BSTNode* lt; + BSTNode* rt; + BSTNode* par; + item; + BSTNode( h, BSTNode* l=0, BSTNode* r=0, + BSTNode* p = 0); + ~BSTNode(); +}; + +inline BSTNode::BSTNode( h, BSTNode* l, BSTNode* r, + BSTNode* p) +:item(h), lt(l), rt(r), par(p) {} + +inline BSTNode::~BSTNode() {} + +typedef BSTNode* BSTNodePtr; + +#endif + +class BSTSet : public Set +{ +protected: + BSTNode* root; + + BSTNode* leftmost(); + BSTNode* rightmost(); + BSTNode* pred(BSTNode* t); + BSTNode* succ(BSTNode* t); + void _kill(BSTNode* t); + BSTNode* _copy(BSTNode* t); + +public: + BSTSet(); + BSTSet(BSTSet& a); + ~BSTSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + int operator == (BSTSet& b); + int operator != (BSTSet& b); + int operator <= (BSTSet& b); + + void balance(); + int OK(); +}; + +inline BSTSet::~BSTSet() +{ + _kill(root); +} + +inline BSTSet::BSTSet() +{ + root = 0; + count = 0; +} + + +inline BSTSet::BSTSet(BSTSet& a) +{ + count = a.count; + root = _copy(a.root); +} + +inline int BSTSet::operator != (BSTSet& b) +{ + return ! (*this == b); +} + +inline Pix BSTSet::first() +{ + return Pix(leftmost()); +} + +inline Pix BSTSet::last() +{ + return Pix(rightmost()); +} + +inline void BSTSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((BSTNode*)i)); +} + +inline void BSTSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((BSTNode*)i)); +} + +inline & BSTSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((BSTNode*)i)->item; +} + +inline void BSTSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int BSTSet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Bag.ccP b/gnu/lib/libg++/g++-include/Bag.ccP new file mode 100644 index 0000000000..836d0d6656 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Bag.ccP @@ -0,0 +1,74 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".Bag.h" + +// error handling + +void Bag::error(const char* msg) +{ + (*lib_error_handler)("Bag", msg); +} + + +Pix Bag::seek( item, Pix i) +{ + if (i == 0) + i = first(); + else + next(i); + for (;i != 0 && (!(EQ((*this)(i), item))); next(i)); + return i; +} + +int Bag::owns(Pix p) +{ + if (p == 0) return 0; + for (Pix i = first(); i != 0; next(i)) if (i == p) return 1; + return 0; +} + +void Bag::remove( item) +{ + int i = nof(item); + while (i-- > 0) del(item); +} + + +int Bag::nof( item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (EQ((*this)(p), item)) ++n; + return n; +} + +void Bag::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + + diff --git a/gnu/lib/libg++/g++-include/Bag.hP b/gnu/lib/libg++/g++-include/Bag.hP new file mode 100644 index 0000000000..4b9a87a909 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Bag.hP @@ -0,0 +1,79 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Bag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Bag_h 1 + +#include +#include ".defs.h" + +class Bag +{ +protected: + int count; + +public: + virtual ~Bag(); + + int length(); // current number of items + int empty(); + + virtual Pix add( item) = 0; // add item; return Pix + + virtual void del( item) = 0; // delete 1 occurrence of item +#undef remove + virtual void remove( item); // delete all occurrences + virtual void clear(); // delete all items + + virtual int contains( item); // is item in Bag? + virtual int nof( item); // how many in Bag? + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + + virtual & operator () (Pix i) = 0; // access item at i + + virtual Pix seek( item, Pix from=0); // Pix of next occurrence + virtual int owns(Pix i); // is i a valid Pix ? + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline Bag::~Bag() {} + +inline int Bag::length() +{ + return count; +} + +inline int Bag::empty() +{ + return count == 0; +} + +inline int Bag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/CHBag.ccP b/gnu/lib/libg++/g++-include/CHBag.ccP new file mode 100644 index 0000000000..16649ac22f --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHBag.ccP @@ -0,0 +1,209 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHBag.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHBag::CHBag(unsigned int sz) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHBag::CHBag(CHBag& a) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix CHBag::seek( key, Pix i) +{ + CHNode* p = (CHNode*)i; + if (p == 0 || !EQ(p->hd, key)) + { + unsigned int h = HASH(key) % size; + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + } + else + { + for (p = p->tl; goodCHptr(p); p = p->tl) + if (EQ(p->hd, key)) + return Pix(p); + } + return 0; +} + +int CHBag::nof( key) +{ + int n = 0; + unsigned int h = HASH(key) % size; + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) ++n; + return n; +} + + +Pix CHBag::add( item) +{ + unsigned int h = HASH(item) % size; + CHNode* t = new CHNode(item); + t->tl = tab[h]; + tab[h] = t; + ++count; + return Pix(t); +} + +void CHBag::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + +void CHBag::remove( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + --count; + if (trail == t) + { + tab[h] = t->tl; + delete t; + t = trail = tab[h]; + } + else + { + trail->tl = t->tl; + delete t; + t = trail->tl; + } + } + else + { + trail = t; + t = t->tl; + } + } +} + + +void CHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHBag::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHBag::next(Pix& p) +{ + if (p == 0) return; + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int CHBag::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/CHBag.hP b/gnu/lib/libg++/g++-include/CHBag.hP new file mode 100644 index 0000000000..f6ca10b3b9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHBag.hP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHBag_h 1 + +#include ".Bag.h" + + +#include ".CHNode.h" + +class CHBag : public Bag +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + CHBag(CHBag& a); + ~CHBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline CHBag::~CHBag() +{ + clear(); + delete tab; +} + +inline int CHBag::contains( key) +{ + return seek(key) != 0; +} + +inline & CHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((CHNode*)i)->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/CHMap.ccP b/gnu/lib/libg++/g++-include/CHMap.ccP new file mode 100644 index 0000000000..1bd76db5fc --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHMap.ccP @@ -0,0 +1,166 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "..CHMap.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHMap::CHMap( dflt, unsigned int sz) + :Map(dflt) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHMap::CHMap(CHMap& a) :Map(a.def) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +Pix CHMap::seek( key) +{ + unsigned int h = HASH(key) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +& CHMap::operator []( item) +{ + unsigned int h = HASH(item) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(item, t->hd)) + return t->cont; + + t = new CHNode(item, def, tab[h]); + tab[h] = t; + ++count; + return t->cont; +} + + +void CHMap::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void CHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHMap::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHMap::next(Pix& p) +{ + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + + +int CHMap::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/CHMap.hP b/gnu/lib/libg++/g++-include/CHMap.hP new file mode 100644 index 0000000000..95441a3544 --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHMap.hP @@ -0,0 +1,104 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHMap_h 1 + +#include "..Map.h" + +#ifndef _CHNode_h +#define _CHNode_h 1 + +struct CHNode +{ + CHNode* tl; + hd; + cont; + CHNode(); + CHNode( h, c, CHNode* t = 0); + ~CHNode(); +}; + +inline CHNode::CHNode() {} + +inline CHNode::CHNode( h, c, CHNode* t) + : hd(h), cont(c), tl(t) {} + +inline CHNode::~CHNode() {} + +typedef CHNode* CHNodePtr; + +#endif + + +class CHMap : public Map +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHMap( dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + CHMap(CHMap& a); + ~CHMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + int OK(); +}; + + +inline CHMap::~CHMap() +{ + clear(); + delete tab; +} + +inline int CHMap::contains( key) +{ + return seek(key) != 0; +} + +inline & CHMap::key(Pix p) +{ + if (p == 0) error("null Pix"); + return ((CHNode*)p)->hd; +} + +inline & CHMap::contents(Pix p) +{ + if (p == 0) error("null Pix"); + return ((CHNode*)p)->cont; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/CHNode.ccP b/gnu/lib/libg++/g++-include/CHNode.ccP new file mode 100644 index 0000000000..e16725fd74 --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHNode.h" diff --git a/gnu/lib/libg++/g++-include/CHNode.hP b/gnu/lib/libg++/g++-include/CHNode.hP new file mode 100644 index 0000000000..84e67d069b --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHNode.hP @@ -0,0 +1,43 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _CHNode_h +#define _CHNode_h 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include ".defs.h" + +struct CHNode +{ + CHNode* tl; + hd; + CHNode(); + CHNode( h, CHNode* t = 0); + ~CHNode(); +}; + +inline CHNode::CHNode() {} + +inline CHNode::CHNode( h, CHNode* t) :hd(h), tl(t) {} + +inline CHNode::~CHNode() {} + +typedef CHNode* CHNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/CHSet.ccP b/gnu/lib/libg++/g++-include/CHSet.ccP new file mode 100644 index 0000000000..330506cb19 --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHSet.ccP @@ -0,0 +1,271 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHSet.h" + +// A CHSet is implemented as an array (tab) of buckets, each of which +// contains a pointer to a list of CHNodes. Each node contains a +// pointer to the next node in the list, and a pointer to the . +// The end of the list is marked by a next node pointer which is odd +// when considered as an integer (least significant bit = 1). The +// assumption is that CHNodes will all begin on even addresses. If +// the odd pointer is right-shifted by one bit, it becomes the index +// within the tab array of the next bucket (that is, bucket i has +// next bucket pointer 2*(i+1)+1). + +// The bucket pointers are initialized by the constructor and +// used to support the next(Pix&) method. + +// This implementation is not portable to machines with different +// pointer and integer sizes, or on which CHNodes might be aligned on +// odd byte boundaries, but allows the same pointer to be used for +// chaining within a bucket and to the next bucket. + + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHSet::CHSet(unsigned int sz) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHSet::CHSet(CHSet& a) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix CHSet::seek( key) +{ + unsigned int h = HASH(key) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +Pix CHSet::add( item) +{ + unsigned int h = HASH(item) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(item, t->hd)) + return Pix(t); + + ++count; + t = new CHNode(item, tab[h]); + tab[h] = t; + return Pix(t); +} + + +void CHSet::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void CHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHSet::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHSet::next(Pix& p) +{ + if (p == 0) return; + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int CHSet::operator == (CHSet& b) +{ + if (count != b.count) + return 0; + else + { + CHNode* p; + for (unsigned int i = 0; i < size; ++i) + for (p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + for (i = 0; i < b.size; ++i) + for (p = b.tab[i]; goodCHptr(p); p = p->tl) + if (seek(p->hd) == 0) + return 0; + return 1; + } +} + +int CHSet::operator <= (CHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + return 1; + } +} + +void CHSet::operator |= (CHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + for (CHNode* p = b.tab[i]; goodCHptr(p); p = p->tl) + add(p->hd); +} + +void CHSet::operator &= (CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* t = tab[i]; + CHNode* trail = t; + while (goodCHptr(t)) + { + CHNode* nxt = t->tl; + if (b.seek(t->hd) == 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +void CHSet::operator -= (CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* t = tab[i]; + CHNode* trail = t; + while (goodCHptr(t)) + { + CHNode* nxt = t->tl; + if (b.seek(t->hd) != 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +int CHSet::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/CHSet.hP b/gnu/lib/libg++/g++-include/CHSet.hP new file mode 100644 index 0000000000..f0a08de4ce --- /dev/null +++ b/gnu/lib/libg++/g++-include/CHSet.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHSet_h 1 + +#include ".Set.h" +#include ".CHNode.h" + +class CHSet : public Set +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + CHSet(CHSet& a); + ~CHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (CHSet& b); + void operator -= (CHSet& b); + void operator &= (CHSet& b); + + int operator == (CHSet& b); + int operator != (CHSet& b); + int operator <= (CHSet& b); + + int OK(); +}; + +inline CHSet::~CHSet() +{ + clear(); + delete tab; +} + +inline int CHSet::contains( key) +{ + return seek(key) != 0; +} + +inline & CHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((CHNode*)i)->hd; +} + +inline int CHSet::operator != (CHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/DLDeque.ccP b/gnu/lib/libg++/g++-include/DLDeque.ccP new file mode 100644 index 0000000000..d5a0db7f91 --- /dev/null +++ b/gnu/lib/libg++/g++-include/DLDeque.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".DLDeque.h" diff --git a/gnu/lib/libg++/g++-include/DLDeque.hP b/gnu/lib/libg++/g++-include/DLDeque.hP new file mode 100644 index 0000000000..d91cdd41cb --- /dev/null +++ b/gnu/lib/libg++/g++-include/DLDeque.hP @@ -0,0 +1,130 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _DLDeque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _DLDeque_h + +#include ".DLList.h" +#include ".Deque.h" + +class DLDeque : public Deque +{ + DLList p; + +public: + DLDeque(); + DLDeque(const DLDeque& d); + ~DLDeque(); + + void operator = (const DLDeque&); + + void push( item); // insert at front + void enq( item); // insert at rear + + & front(); + & rear(); + + deq(); + void del_front(); + void del_rear(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + + +inline DLDeque::DLDeque() : p() {} +inline DLDeque::DLDeque(const DLDeque& d) : p(d.p) {} + +inline DLDeque::~DLDeque() {} + +inline void DLDeque::push(item) +{ + p.prepend(item); +} + +inline void DLDeque::enq(item) +{ + p.append(item); +} + +inline DLDeque::deq() +{ + return p.remove_front(); +} + +inline & DLDeque::front() +{ + return p.front(); +} + +inline & DLDeque::rear() +{ + return p.rear(); +} + +inline void DLDeque::del_front() +{ + p.del_front(); +} + +inline void DLDeque::del_rear() +{ + p.del_rear(); +} + +inline void DLDeque::operator =(const DLDeque& s) +{ + p.operator = (s.p); +} + + +inline int DLDeque::empty() +{ + return p.empty(); +} + +inline int DLDeque::full() +{ + return 0; +} + +inline int DLDeque::length() +{ + return p.length(); +} + +inline int DLDeque::OK() +{ + return p.OK(); +} + +inline void DLDeque::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/DLList.ccP b/gnu/lib/libg++/g++-include/DLList.ccP new file mode 100644 index 0000000000..cb1e22a337 --- /dev/null +++ b/gnu/lib/libg++/g++-include/DLList.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include +#include ".DLList.h" + +// error handling + + + +void DLList::error(const char* msg) +{ + (*lib_error_handler)("DLList", msg); +} + +int DLList::length() +{ + int l = 0; + DLListNode* t = h; + if (t != 0) do { ++l; t = t->fd; } while (t != h); + return l; +} + +DLList::DLList(const DLList& a) +{ + if (a.h == 0) + h = 0; + else + { + DLListNode* p = a.h; + DLListNode* t = new DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + DLListNode* n = new DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + return; + } +} + +DLList& DLList::operator = (const DLList& a) +{ + if (h != a.h) + { + clear(); + if (a.h != 0) + { + DLListNode* p = a.h; + DLListNode* t = new DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + DLListNode* n = new DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + } + } + return *this; +} + +void DLList::clear() +{ + if (h == 0) + return; + + DLListNode* p = h->fd; + h->fd = 0; + h = 0; + + while (p != 0) + { + DLListNode* nxt = p->fd; + delete(p); + p = nxt; + } +} + + +Pix DLList::prepend( item) +{ + DLListNode* t = new DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->fd = h; + t->bk = h->bk; + h->bk->fd = t; + h->bk = t; + h = t; + } + return Pix(t); +} + +Pix DLList::append( item) +{ + DLListNode* t = new DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->bk = h->bk; + t->bk->fd = t; + t->fd = h; + h->bk = t; + } + return Pix(t); +} + +Pix DLList::ins_after(Pix p, item) +{ + if (p == 0) return prepend(item); + DLListNode* u = (DLListNode*) p; + DLListNode* t = new DLListNode(item, u, u->fd); + u->fd->bk = t; + u->fd = t; + return Pix(t); +} + +Pix DLList::ins_before(Pix p, item) +{ + if (p == 0) error("null Pix"); + DLListNode* u = (DLListNode*) p; + DLListNode* t = new DLListNode(item, u->bk, u); + u->bk->fd = t; + u->bk = t; + if (u == h) h = t; + return Pix(t); +} + +void DLList::join(DLList& b) +{ + DLListNode* t = b.h; + b.h = 0; + if (h == 0) + h = t; + else if (t != 0) + { + DLListNode* l = t->bk; + h->bk->fd = t; + t->bk = h->bk; + h->bk = l; + l->fd = h; + } +} + +int DLList::owns(Pix p) +{ + DLListNode* t = h; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->fd; + } while (t != h); + } + return 0; +} + +void DLList::del(Pix& p, int dir) +{ + if (p == 0) error("null Pix"); + DLListNode* t = (DLListNode*) p; + if (t->fd == t) + { + h = 0; + p = 0; + } + else + { + if (dir < 0) + { + if (t == h) + p = 0; + else + p = Pix(t->bk); + } + else + { + if (t == h->bk) + p = 0; + else + p = Pix(t->fd); + } + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + +void DLList::del_after(Pix& p) +{ + if (p == 0) + { + del_front(); + return; + } + + DLListNode* b = (DLListNode*) p; + DLListNode* t = b->fd; + + if (b == t) + { + h = 0; + p = 0; + } + else + { + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + + DLList::remove_front() +{ + if (h == 0) + error("remove_front of empty list"); + DLListNode* t = h; + res = t->hd; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; + return res; +} + + +void DLList::del_front() +{ + if (h == 0) + error("del_front of empty list"); + DLListNode* t = h; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; +} + + DLList::remove_rear() +{ + if (h == 0) + error("remove_rear of empty list"); + DLListNode* t = h->bk; + res = t->hd; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; + return res; +} + + +void DLList::del_rear() +{ + if (h == 0) + error("del_rear of empty list"); + DLListNode* t = h->bk; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; +} + + +int DLList::OK() +{ + int v = 1; + if (h != 0) + { + DLListNode* t = h; + long count = MAXLONG; // Lots of chances to find h! + do + { + count--; + v &= t->bk->fd == t; + v &= t->fd->bk == t; + t = t->fd; + } while (v && count > 0 && t != h); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/DLList.hP b/gnu/lib/libg++/g++-include/DLList.hP new file mode 100644 index 0000000000..b115ab9f6f --- /dev/null +++ b/gnu/lib/libg++/g++-include/DLList.hP @@ -0,0 +1,157 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _DLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _DLList_h 1 + +#include +#include ".defs.h" + +#ifndef _DLListNode_h +#define _DLListNode_h 1 + +struct DLListNode +{ + DLListNode* bk; + DLListNode* fd; + hd; + DLListNode(); + DLListNode(const h, + DLListNode* p = 0, + DLListNode* n = 0); + ~DLListNode(); +}; + +inline DLListNode::DLListNode() {} + +inline DLListNode::DLListNode(const h, DLListNode* p, + DLListNode* n) + :hd(h), bk(p), fd(n) {} + +inline DLListNode::~DLListNode() {} + +typedef DLListNode* DLListNodePtr; + +#endif + +class DLList +{ + friend class DLListTrav; + + DLListNode* h; + +public: + DLList(); + DLList(const DLList& a); + ~DLList(); + + DLList& operator = (const DLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend( item); + Pix append( item); + void join(DLList&); + + & front(); + remove_front(); + void del_front(); + + & rear(); + remove_rear(); + void del_rear(); + + & operator () (Pix p); + Pix first(); + Pix last(); + void next(Pix& p); + void prev(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, item); + Pix ins_before(Pix p, item); + void del(Pix& p, int dir = 1); + void del_after(Pix& p); + + void error(const char* msg); + int OK(); +}; + + +inline DLList::~DLList() +{ + clear(); +} + +inline DLList::DLList() +{ + h = 0; +} + +inline int DLList::empty() +{ + return h == 0; +} + + +inline void DLList::next(Pix& p) +{ + p = (p == 0 || p == h->bk)? 0 : Pix(((DLListNode*)p)->fd); +} + +inline void DLList::prev(Pix& p) +{ + p = (p == 0 || p == h)? 0 : Pix(((DLListNode*)p)->bk); +} + +inline Pix DLList::first() +{ + return Pix(h); +} + +inline Pix DLList::last() +{ + return (h == 0)? 0 : Pix(h->bk); +} + +inline & DLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((DLListNode*)p)->hd; +} + +inline & DLList::front() +{ + if (h == 0) error("front: empty list"); + return h->hd; +} + +inline & DLList::rear() +{ + if (h == 0) error("rear: empty list"); + return h->bk->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Deque.ccP b/gnu/lib/libg++/g++-include/Deque.ccP new file mode 100644 index 0000000000..79a9b72c87 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Deque.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Deque.h" + +Deque::~Deque() {} + +void Deque::error(const char* msg) +{ + (*lib_error_handler)("Deque", msg); +} diff --git a/gnu/lib/libg++/g++-include/Deque.hP b/gnu/lib/libg++/g++-include/Deque.hP new file mode 100644 index 0000000000..7ec52d4a0c --- /dev/null +++ b/gnu/lib/libg++/g++-include/Deque.hP @@ -0,0 +1,57 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Deque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Deque_h + +#include + +#include ".defs.h" + +class Deque +{ +public: + Deque() { } + virtual ~Deque(); + + virtual void push( item) = 0; // insert at front + virtual void enq( item) = 0; // insert at rear + + virtual & front() = 0; + virtual & rear() = 0; + + virtual deq() = 0; + virtual void del_front() = 0; + virtual void del_rear() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + virtual void clear() = 0; + + virtual int OK() = 0; + + void error(const char*); +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/FPQueue.ccP b/gnu/lib/libg++/g++-include/FPQueue.ccP new file mode 100644 index 0000000000..a358cacb60 --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPQueue.h" diff --git a/gnu/lib/libg++/g++-include/FPQueue.hP b/gnu/lib/libg++/g++-include/FPQueue.hP new file mode 100644 index 0000000000..f647ae9dfd --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPQueue.hP @@ -0,0 +1,112 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _FPQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPQueue_h + +#include ".FPlex.h" +#include ".Queue.h" + +class FPQueue : public Queue +{ + FPlex p; + +public: + FPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY); + FPQueue(const FPQueue& q); + ~FPQueue(); + + void operator = (const FPQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline FPQueue::FPQueue(int chunksize) : p(chunksize) {} +inline FPQueue::FPQueue(const FPQueue& q) : p(q.p) {} + +inline FPQueue::~FPQueue() {} + +inline void FPQueue::enq(item) +{ + p.add_high(item); +} + +inline FPQueue::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & FPQueue::front() +{ + return p.low_element(); +} + + +inline void FPQueue::del_front() +{ + p.del_low(); +} + +inline void FPQueue::operator =(const FPQueue& s) +{ + p = s.p; +} + +inline int FPQueue::empty() +{ + return p.empty(); +} + +inline int FPQueue::full() +{ + return p.full(); +} + +inline int FPQueue::length() +{ + return p.length(); +} + +inline int FPQueue::OK() +{ + return p.OK(); +} + +inline void FPQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/FPStack.ccP b/gnu/lib/libg++/g++-include/FPStack.ccP new file mode 100644 index 0000000000..954991193b --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPStack.h" diff --git a/gnu/lib/libg++/g++-include/FPStack.hP b/gnu/lib/libg++/g++-include/FPStack.hP new file mode 100644 index 0000000000..091f255360 --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPStack.hP @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _FPStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPStack_h + +#include ".FPlex.h" +#include ".Stack.h" + +class FPStack : public Stack +{ + FPlex p; + +public: + FPStack(int chunksize = DEFAULT_INITIAL_CAPACITY); + FPStack(const FPStack& s); + ~FPStack(); + + void operator = (const FPStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + + +inline FPStack::FPStack(int chunksize) : p(chunksize) {} +inline FPStack::FPStack(const FPStack& s) : p(s.p) {} + +inline FPStack::~FPStack() {} + +inline void FPStack::push(item) +{ + p.add_high(item); +} + +inline FPStack::pop() +{ + res = p.high_element(); + p.del_high(); + return res; +} + +inline & FPStack::top() +{ + return p.high_element(); +} + +inline void FPStack::del_top() +{ + p.del_high(); +} + +inline void FPStack::operator =(const FPStack& s) +{ + p = s.p; +} + +inline int FPStack::empty() +{ + return p.empty(); +} + +inline int FPStack::full() +{ + return p.full(); +} + +inline int FPStack::length() +{ + return p.length(); +} + +inline int FPStack::OK() +{ + return p.OK(); +} + +inline void FPStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/FPlex.ccP b/gnu/lib/libg++/g++-include/FPlex.ccP new file mode 100644 index 0000000000..70d6c47557 --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPlex.ccP @@ -0,0 +1,167 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPlex.h" + + +FPlex:: FPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); +} + +FPlex:: FPlex(int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (maxsize > 0) + { + csize = maxsize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + * data = new [csize]; + hd = new IChunk(data, maxsize, lo, fnc, fnc); + } +} + + +FPlex:: FPlex(int l, int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (maxsize > 0) + { + csize = maxsize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -maxsize; + * data = new [csize]; + hd = new IChunk(data, maxsize+lo, lo, fnc, fnc); + } +} + +FPlex:: FPlex(int l, int hi, const initval, int maxsize) +{ + lo = l; + fnc = hi + 1; + if (maxsize >= 0) + { + csize = maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + * data = new [csize]; + hd = new IChunk(data, -csize, lo, fnc, fnc); + } + fill(initval); +} + +FPlex::FPlex(const FPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void FPlex::operator= (const FPlex& a) +{ + if (&a != this) + { + del_chunk(hd); + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void FPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + +void FPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void FPlex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + +void FPlex::clear() +{ + if (fnc != lo) + { + hd->clear(lo); + fnc = lo; + } +} + +int FPlex::OK () const +{ + int v = hd != 0; // hd exists + v &= hd->IChunk::OK(); // and is OK + v &= fnc - lo <= hd->size(); // and has enough space + v &= lo <= fnc; // plex indices consistent + v &= lo == hd->low_index(); // and match those + v &= fnc == hd->fence_index(); // of chunk + v &= one_chunk(); // and only one chunk + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/FPlex.hP b/gnu/lib/libg++/g++-include/FPlex.hP new file mode 100644 index 0000000000..eb93a0c372 --- /dev/null +++ b/gnu/lib/libg++/g++-include/FPlex.hP @@ -0,0 +1,253 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _FPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPlex_h 1 + +#include ".Plex.h" + +class FPlex : public Plex +{ +public: + FPlex(); // set low = 0; + // fence = 0; + // csize = default + + FPlex(int maxsize); // low = 0; + // fence = 0; + // csize = maxsize + + FPlex(int lo, // low = lo; + int maxsize); // fence=lo + // csize = maxsize + + FPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int maxsize = 0); // csize = maxsize + // or fence - lo if 0 + + FPlex(const FPlex&); // X(X&) + + ~FPlex(); + + void operator= (const FPlex&); + +// virtuals + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int OK () const; +}; + + +inline int FPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int FPlex::low() const +{ + return lo; +} + +inline int FPlex::high() const +{ + return fnc - 1; +} + +inline Pix FPlex::first() const +{ + return (Pix)(hd->IChunk::first_pointer()); +} + +inline void FPlex::prev(Pix& p) const +{ + p = Pix(hd->IChunk::pred((*) p)); +} + +inline void FPlex::next(Pix& p) const +{ + p = Pix(hd->IChunk::succ((*) p)); +} + +inline Pix FPlex::last() const +{ + return Pix(hd->IChunk::last_pointer()); +} + +inline int FPlex::full () const +{ + return fnc - lo == csize; +} + +inline void FPlex::prev(int& idx) const +{ + --idx; +} + +inline void FPlex::next(int& idx) const +{ + ++idx; +} + +inline & FPlex:: operator [] (int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline & FPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline & FPlex::low_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline & FPlex::high_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline const & FPlex:: operator [] (int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline const & FPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline const & FPlex::low_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline const & FPlex::high_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline int FPlex::can_add_high() const +{ + return hd->can_grow_high(); +} + +inline int FPlex::can_add_low() const +{ + return hd->can_grow_low(); +} + +inline int FPlex::add_high(const elem) +{ + if (!can_add_high()) full_error(); + *((hd->IChunk::grow_high())) = elem; + return fnc++; +} + +inline int FPlex::del_high () +{ + if (empty()) empty_error(); + hd->IChunk::shrink_high(); + return --fnc - 1; +} + +inline int FPlex::add_low (const elem) +{ + if (!can_add_low()) full_error(); + *((hd->IChunk::grow_low())) = elem; + return --lo; +} + +inline int FPlex::del_low () +{ + if (empty()) empty_error(); + hd->IChunk::shrink_low(); + return ++lo; +} + +inline int FPlex::owns (Pix p) const +{ + return hd->actual_pointer((*)p); +} + +inline int FPlex::Pix_to_index(Pix p) const +{ + if (!hd->actual_pointer((const *)p)) index_error(); + return hd->index_of((const *)p); +} + +inline Pix FPlex::index_to_Pix(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return Pix(hd->pointer_to(idx)); +} + +inline FPlex::~FPlex() {} + +#endif diff --git a/gnu/lib/libg++/g++-include/List.ccP b/gnu/lib/libg++/g++-include/List.ccP new file mode 100644 index 0000000000..2afbdaf972 --- /dev/null +++ b/gnu/lib/libg++/g++-include/List.ccP @@ -0,0 +1,956 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".List.h" + +ListNode NilListNode; + +class init_NilListNode +{ +public: + init_NilListNode() + { + NilListNode.tl = &NilListNode; + NilListNode.ref = -1; + } +}; + +static init_NilListNode NilListNode_initializer; + +List& List::operator = (List& a) +{ + reference(a.P); + dereference(P); + P = a.P; + return *this; +} + + List::pop() +{ + res = P->hd; + ListNode* tail = P->tl; + reference(tail); + dereference(P); + P = tail; + return res; +} + +void List::set_tail(List& a) +{ + reference(a.P); + dereference(P->tl); + P->tl = a.P; +} + +List List::nth(int n) +{ + for (ListNode* p = P; n-- > 0; p = p->tl); + reference(p); + return List(p); +} + +List List::last() +{ + ListNode* p = P; + if (p != &NilListNode) while (p->tl != &NilListNode) p = p->tl; + reference(p); + return List(p); +} + +void List::append(List& l) +{ + ListNode* p = P; + ListNode* a = l.P; + reference(a); + if (p != &NilListNode) + { + while (p->tl != &NilListNode) p = p->tl; + p->tl = a; + } + else + P = a; +} + +int List::length() +{ + int l = 0; + for (ListNode* p = P; p != &NilListNode; p = p->tl) ++l; + return l; +} + +& List::operator [] (int n) +{ + for (ListNode* p = P; n-- > 0; p = p->tl); + return (p->hd); +} + +int operator == (List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + + for (;;) + { + if (a == &NilListNode) + return b == &NilListNode; + else if (b == &NilListNode) + return 0; + else if (EQ(a->hd, b->hd)) + { + a = a->tl; + b = b->tl; + } + else + return 0; + } +} + + +void List::apply(Procedure f) +{ + for(ListNode* p = P; p != &NilListNode; p = p->tl) + (*f)((p->hd)); +} + +void List::subst( old, repl) +{ + for(ListNode* p = P; p != &NilListNode; p = p->tl) + if (EQ(p->hd, old)) + p->hd = repl; +} + + List::reduce(Combiner f, base) +{ + r = base; + for(ListNode* p = P; p != &NilListNode; p = p->tl) + r = (*f)(r, (p->hd)); + return r; +} + +int List::position( targ) +{ + int l = 0; + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return -1; + else if (EQ(p->hd, targ)) + return l; + else + { + ++l; + p = p->tl; + } + } +} + +int List::contains( targ) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (EQ(p->hd, targ)) + return 1; + else + p = p->tl; + } +} + +List List::find( targ) +{ + ListNode* p = P; + while (p != &NilListNode && !EQ(p->hd, targ)) + p=p->tl; + reference(p); + return List(p); +} + +Pix List::seek( targ) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (EQ(p->hd, targ)) + return Pix(p); + else + p = p->tl; + } +} + +int List::owns(Pix i) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (Pix(p) == i) + return 1; + else + p = p->tl; + } +} + +List List::find(List& target) +{ + ListNode* targ = target.P; + if (targ == &NilListNode) + return List(targ); + + ListNode* p = P; + while (p != &NilListNode) + { + if (EQ(p->hd, targ->hd)) + { + ListNode* a = p->tl; + ListNode* t = targ->tl; + for(;;) + { + if (t == &NilListNode) + { + reference(p); + return List(p); + } + else if (a == &NilListNode || !EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return List(&NilListNode); +} + +int List::contains(List& target) +{ + ListNode* targ = target.P; + if (targ == &NilListNode) + return 0; + + ListNode* p = P; + while (p != &NilListNode) + { + if (EQ(p->hd, targ->hd)) + { + ListNode* a = p->tl; + ListNode* t = targ->tl; + for(;;) + { + if (t == &NilListNode) + return 1; + else if (a == &NilListNode || !EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return 0; +} + +void List::del( targ) +{ + ListNode* h = P; + + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if (EQ(h->hd, targ)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if (EQ(p->hd, targ)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::del(Predicate f) +{ + ListNode* h = P; + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if ((*f)(h->hd)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if ((*f)(p->hd)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::select(Predicate f) +{ + ListNode* h = P; + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if (!(*f)(h->hd)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if (!(*f)(p->hd)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::reverse() +{ + ListNode* l = &NilListNode; + ListNode* p = P; + while (p != &NilListNode) + { + ListNode* nxt = p->tl; + p->tl = l; + l = p; + p = nxt; + } + P = l; +} + + +List copy(List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } +} + + +List subst( old, repl, List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* h = new ListNode; + h->ref = 1; + if (EQ(a->hd, old)) + h->hd = repl; + else + h->hd = a->hd; + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = new ListNode; + n->ref = 1; + if (EQ(a->hd, old)) + n->hd = repl; + else + n->hd = a->hd; + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } +} + +List combine(Combiner f, List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + if (a == &NilListNode || b == &NilListNode) + return List(&NilListNode); + else + { + ListNode* h = newListNode((*f)(a->hd, b->hd)); + ListNode* trail = h; + a = a->tl; + b = b->tl; + while (a != &NilListNode && b != &NilListNode) + { + ListNode* n = newListNode((*f)(a->hd, b->hd)); + trail->tl = n; + trail = n; + a = a->tl; + b = b->tl; + } + trail->tl = &NilListNode; + return List(h); + } +} + +List reverse(List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* l = newListNode(a->hd); + l->tl = &NilListNode; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + n->tl = l; + l = n; + } + return List(l); + } +} + +List append(List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + reference(b); + if (a != &NilListNode) + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = b; + return List(h); + } + else + return List(b); +} + +void List::prepend(List& y) +{ + ListNode* b = y.P; + if (b != &NilListNode) + { + ListNode* h = newListNode(b->hd); + ListNode* trail = h; + for(b = b->tl; b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = P; + P = h; + } +} + +List concat(List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + if (a != &NilListNode) + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + }; + for(;b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } + else if (b != &NilListNode) + { + ListNode* h = newListNode(b->hd); + ListNode* trail = h; + for(b = b->tl; b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } + else + return List(&NilListNode); +} + +List select(Predicate f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if ((*f)(a->hd)) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if ((*f)(a->hd)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List remove(Predicate f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if (!(*f)(a->hd)) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if (!(*f)(a->hd)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List remove( targ, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if (!(EQ(a->hd, targ))) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if (!EQ(a->hd, targ)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List map(Mapper f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + if (a != &NilListNode) + { + h = newListNode((*f)(a->hd)); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode((*f)(a->hd)); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + } + return List(h); +} + + +List merge(List& x, List& y, Comparator f) +{ + ListNode* a = x.P; + ListNode* b = y.P; + + if (a == &NilListNode) + { + if (b == &NilListNode) + return List(&NilListNode); + else + return copy(y); + } + else if (b == &NilListNode) + return copy(x); + + ListNode* h = new ListNode; + h->ref = 1; + if ((*f)(a->hd, b->hd) <= 0) + { + h->hd = a->hd; + a = a->tl; + } + else + { + h->hd = b->hd; + b = b->tl; + } + + ListNode* r = h; + + for(;;) + { + if (a == &NilListNode) + { + while (b != &NilListNode) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + r->tl = &NilListNode; + return List(h); + } + else if (b == &NilListNode) + { + while (a != &NilListNode) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + r->tl = &NilListNode; + return List(h); + } + else if ((*f)(a->hd, b->hd) <= 0) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + else + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + } +} + +void List::sort(Comparator f) +{ + // strategy: place runs in queue, merge runs until done + // This is often very fast + + if (P == &NilListNode || P->tl == &NilListNode) + return; + + int qlen = 250; // guess a good queue size, realloc if necessary + + ListNode** queue = (ListNode**)malloc(qlen * sizeof(ListNode*)); + + ListNode* h = P; + ListNode* a = h; + ListNode* b = a->tl; + int qin = 0; + + while (b != &NilListNode) + { + if ((*f)(a->hd, b->hd) > 0) + { + if (h == a) // minor optimization: ensure runlen >= 2 + { + h = b; + a->tl = b->tl; + b->tl = a; + b = a->tl; + } + else + { + if (qin >= qlen) + { + qlen *= 2; + queue = (ListNode**)realloc(queue, qlen * sizeof(ListNode*)); + } + queue[qin++] = h; + a->tl = &NilListNode; + h = a = b; + b = b->tl; + } + } + else + { + a = b; + b = b->tl; + } + } + + int count = qin; + queue[qin] = h; + if (++qin >= qlen) qin = 0; + int qout = 0; + + while (count-- > 0) + { + a = queue[qout]; + if (++qout >= qlen) qout = 0; + b = queue[qout]; + if (++qout >= qlen) qout = 0; + + if ((*f)(a->hd, b->hd) <= 0) + { + h = a; + a = a->tl; + } + else + { + h = b; + b = b->tl; + } + queue[qin] = h; + if (++qin >= qlen) qin = 0; + + for (;;) + { + if (a == &NilListNode) + { + h->tl = b; + break; + } + else if (b == &NilListNode) + { + h->tl = a; + break; + } + else if ((*f)(a->hd, b->hd) <= 0) + { + h->tl = a; + h = a; + a = a->tl; + } + else + { + h->tl = b; + h = b; + b = b->tl; + } + } + } + P = queue[qout]; + free(queue); +} + +int List::list_length() +{ + ListNode* fast = P; + if (fast == &NilListNode) + return 0; + + ListNode* slow = fast->tl; + if (slow == &NilListNode) + return 1; + + fast = slow->tl; + int n = 2; + + for (;;) + { + if (fast == &NilListNode) + return n; + else if (fast->tl == &NilListNode) + return n+1; + else if (fast == slow) + return -1; + else + { + n += 2; + fast = fast->tl->tl; + slow = slow->tl; + } + } +} + +void List::error(const char* msg) +{ + (*lib_error_handler)("List", msg); +} + +int List::OK() +{ + int v = P != 0; // have a node + // check that all nodes OK, even if circular: + + ListNode* fast = P; + if (fast != &NilListNode) + { + v &= fast->ref != 0; + ListNode* slow = fast->tl; + v &= slow->ref != 0; + if (v && slow != &NilListNode) + { + fast = slow->tl; + v &= fast->ref != 0; + while (v) + { + if (fast == &NilListNode) + break; + else if (fast->tl == &NilListNode) + break; + else if (fast == slow) + break; + else + { + v &= fast->ref != 0 && slow->ref != 0; + fast = fast->tl->tl; + slow = slow->tl; + } + } + } + } + if (!v) error ("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/List.hP b/gnu/lib/libg++/g++-include/List.hP new file mode 100644 index 0000000000..7ccdbc3bc4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/List.hP @@ -0,0 +1,273 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _List_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _List_h 1 + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)(); +typedef (*Mapper)(); +typedef (*Combiner)(, ); +typedef int (*Predicate)(); +typedef int (*Comparator)(, ); +#endif + +#include +#include ".defs.h" + +struct ListNode +{ + ListNode* tl; + short ref; + hd; +}; + +extern ListNode NilListNode; + +class List +{ +protected: + ListNode* P; + + List(ListNode* p); +public: + List(); + List( head); + List( head, List& tl); + List(List& a); + List(Pix p); + ~List(); + + List& operator = (List& a); + + int null(); + int valid(); + operator const void* (); + int operator ! (); + + int length(); + int list_length(); + + & get(); + & head(); + & operator [] (int n); + + List nth(int n); + List tail(); + List last(); + + List find( targ); + List find(List& targ); + int contains( targ); + int contains(List& targ); + int position( targ); + + friend List copy(List& a); + friend List concat(List& a, List& b); + friend List append(List& a, List& b); + friend List map(Mapper f, List& a); + friend List merge(List& a, List& b, Comparator f); + friend List combine(Combiner f, List& a, List& b); + friend List reverse(List& a); + friend List select(Predicate f, List& a); +#undef remove + friend List remove( targ, List& a); + friend List remove(Predicate f, List& a); + friend List subst( old, repl, List& a); + + void push( x); + pop(); + + void set_tail(List& p); + void append(List& p); + void prepend(List& p); + void del( targ); + void del(Predicate f); + void select(Predicate f); + void subst( old, repl); + void reverse(); + void sort(Comparator f); + + void apply(Procedure f); + reduce(Combiner f, base); + + friend int operator == (List& a, List& b); + friend int operator != (List& a, List& b); + + Pix first(); + void next(Pix& p); + Pix seek( item); + & operator () (Pix p); + int owns(Pix p); + + void error(const char*); + int OK(); +}; + + +inline void reference(ListNode* p) +{ + if (p->ref >= 0) ++p->ref; +} + +inline void dereference(ListNode* p) +{ + while (p->ref > 0 && --p->ref == 0) + { + ListNode* n = p->tl; + delete(p); + p = n; + } +} + + +inline ListNode* newListNode( h) +{ + ListNode* p = new ListNode; + p->ref = 1; + p->hd = h; + return p; +} + +inline ListNode* newListNode( h, ListNode* t) +{ + ListNode* p = new ListNode; + p->ref = 1; + p->hd = h; + p->tl = t; + return p; +} + + +inline List::~List() +{ + dereference(P); +} + +inline List::List() +{ + P = &NilListNode; +} + +inline List::List(ListNode* p) +{ + P = p; +} + +inline List::List( head) +{ + P = newListNode(head); + P->tl = &NilListNode; +} + +inline List::List( head, List& tl) +{ + P = newListNode(head, tl.P); + reference(P->tl); +} + +inline List::List(List& a) +{ + reference(a.P); + P = a.P; +} + + +inline & List::get() +{ + return P->hd; +} + +inline & List::head() +{ + return P->hd; +} + + +inline List List::tail() +{ + reference(P->tl); + return List(P->tl); +} + + + +inline int List::null() +{ + return P == &NilListNode; +} + +inline int List::valid() +{ + return P != &NilListNode; +} + +inline List::operator const void* () +{ + return (P == &NilListNode)? 0 : this; +} + +inline int List::operator ! () +{ + return (P == &NilListNode); +} + + +inline void List::push( head) +{ + ListNode* oldp = P; + P = newListNode(head, oldp); +} + + +inline int operator != (List& x, List& y) +{ + return !(x == y); +} + +inline Pix List::first() +{ + return (P == &NilListNode)? 0 : Pix(P); +} + +inline & List::operator () (Pix p) +{ + return ((ListNode*)p)->hd; +} + +inline void List::next(Pix& p) +{ + if (p != 0) + { + p = Pix(((ListNode*)p)->tl); + if (p == &NilListNode) p = 0; + } +} + +inline List::List(Pix p) +{ + P = (ListNode*)p; + reference(P); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/MPlex.ccP b/gnu/lib/libg++/g++-include/MPlex.ccP new file mode 100644 index 0000000000..89a1bcf9e6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/MPlex.ccP @@ -0,0 +1,845 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".MPlex.h" + +// MChunk support + + +MChunk::MChunk(* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) + : IChunk(d, baseidx, lowidx, fenceidx, topidx) +{ + unused = fence - low; + unsigned msize = (top - base)/_MAP_BITS + 1; + map = (unsigned long *) (new long[msize]); + memset((void*)map, 0, msize * sizeof(long)); +} + +void MChunk:: shrink_high () +{ + if (fence <= low) empty_error(); + --fence; + if (!valid(fence)) + --unused; + else + free(fence); + reset_high(); +} + +void MChunk:: shrink_low () +{ + if (fence <= low) empty_error(); + if (!valid(low)) + --unused; + else + free(low); + ++low; + reset_low(); +} + +void MChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +void MChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +int MChunk::del(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (v) + { + free(idx); + ++unused; + } + return v; +} + + +int MChunk::undel(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (!v) + { + mark(idx); + --unused; + } + return v; +} + +int MChunk::unused_index() const +{ + if (unused_indices() == 0) index_error(); + int slot; + if (low == base) // can traverse 32 slots at a time + { + int blk = 0; + while (map[blk] == ~0L) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(valid(slot)) ++slot; + return slot; +} + +int MChunk::first_index() const +{ + if (empty()) return fence; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return slot; +} + +int MChunk::last_index() const +{ + if (empty()) return low - 1; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return slot; +} + + +int MChunk:: OK() const +{ + int v = data != 0; // have some data + v &= map != 0; // and a map + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= ((MChunk*)(nxt->prev())) == this; // and links are OK + v &= ((MChunk*)(prv->next())) == this; + + int bitcount = 0; // and unused count correct + for (int i = low; i < fence; ++i) if (!valid(i)) ++bitcount; + v &= unused == bitcount; + + if (!v) error("invariant failure"); + return(v); +} + +* MChunk::succ(* p) const +{ + int i = ((int) p - (int) data) / sizeof() + base + 1; + if (p == 0 || i < low) return 0; + while (i < fence && !valid(i)) ++i; + if (i >= fence) return 0; + return pointer_to(i); +} + +* MChunk::pred(* p) const +{ + int i = ((int) p - (int) data) / sizeof() + base - 1; + if (p == 0 || i >= fence) return 0; + while (i >= low && !valid(i)) --i; + if (i < low) return 0; + return pointer_to(i); +} + +* MChunk::first_pointer() const +{ + if (empty()) return 0; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return pointer_to(slot); +} + +* MChunk::last_pointer() const +{ + if (empty()) return 0; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return pointer_to(slot); +} + +MPlex:: MPlex() +{ + unused = 0; + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, lo+csize); +} + +MPlex:: MPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, chunksize, lo, fnc, fnc); + } +} + + +MPlex:: MPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, chunksize+lo, lo, fnc, fnc); + } +} + + +void MPlex::make_initial_chunks(int up) +{ + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + MChunk* h = new MChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + MChunk* h = new MChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + ch = (MChunk*) hd; +} + +MPlex:: MPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + unused = fnc - lo; + for (int i=lo; iMPlex::MPlex(const MPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const IChunk* p = a.hd; + do + { + * data = new [p->size()]; + MChunk* h = new MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } +} + +void MPlex::operator= (const MPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const IChunk* p = a.hd; + do + { + * data = new [p->size()]; + MChunk* h = new MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), + p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } + } +} + +int MPlex::valid(int idx) const +{ + const MChunk* tail = (MChunk*)tl(); + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) return 0; + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (MChunk*)(hd)) return 0; + t = ((MChunk*)(t->prev())); + } + set_cache(t); + return t->MChunk::valid_index(idx); +} + +void MPlex::cache(int idx) const +{ + const MChunk* tail = (MChunk*)tl(); + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) index_error(); + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (MChunk*)hd) index_error(); + t = ((MChunk*)(t->prev())); + } + if (!t->MChunk::valid_index(idx)) index_error(); + set_cache(t); +} + +void MPlex::cache(const * p) const +{ + const MChunk* old = ch; + const MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) index_error(); + } + if (!t->MChunk::valid_pointer(p)) index_error(); + set_cache(t); +} + +int MPlex::owns(Pix px) const +{ + * p = (*)px; + const MChunk* old = ch; + const MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) return 0; + } + set_cache(t); + return t->MChunk::valid_pointer(p); +} + +int MPlex::add_high(const elem) +{ + MChunk* t = ((MChunk*) tl()); + + if (!t->can_grow_high()) + { + * data = new [csize]; + t = (new MChunk(data, fnc,fnc,fnc,fnc+csize)); + t->link_to_prev(tl()); + } + + *((t->MChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int MPlex::add_low (const elem) +{ + MChunk* t = ((MChunk*) hd); + if (!t->can_grow_low()) + { + * data = new [csize]; + hd = new MChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ((MChunk*) hd); + } + + *((t->MChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + +void MPlex::adjust_bounds() +{ + MChunk* t = ((MChunk*) tl()); + + // clean up tail + + t->reset_high(); + while (t->MChunk::empty() && !one_chunk()) + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + if (one_chunk()) + t->reset_high(); + + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc; + + // and head.. + t = ((MChunk*) hd); + t->reset_low(); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo; + + + set_cache(t); +} + +int MPlex::del_high () +{ + if (empty()) empty_error(); + MChunk* t = ((MChunk*) tl()); + while (t->MChunk::empty() && !one_chunk()) // possible stragglers + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + t->MChunk::shrink_high(); + while (t->MChunk::empty() && !one_chunk()) + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc - 1; + set_cache(t); + return fnc - 1; +} + +int MPlex::del_low () +{ + if (empty()) empty_error(); + MChunk* t = ((MChunk*) hd); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + t->MChunk::shrink_low(); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo - 1; + set_cache(t); + return lo; +} + +int MPlex::add(const elem) +{ + if (unused == 0) + return add_high(elem); + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + int i = t->unused_index(); + set_cache(t); + undel_index(i); + (*this)[i] = elem; + return i; +} + +int MPlex::unused_index() const +{ + if (unused == 0) index_error(); + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + set_cache(t); + return t->unused_index(); +} + +Pix MPlex::unused_Pix() const +{ + if (unused == 0) return 0; + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + set_cache(t); + return t->pointer_to(t->unused_index()); +} + +int MPlex::del_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + if (MPlex::valid(idx)) + { + ++unused; + ch->MChunk::del(idx); + return 1; + } + else + return 0; +} + +int MPlex::dopred(int idx) const +{ + + if (idx >= fnc) idx = fnc; + if (idx <= lo) return lo - 1; + + const MChunk* t = ch; + + while (idx > t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx <= t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int i = t->MChunk::pred(idx); + while (i < t->low_index() && i >= lo) + { + t = ((MChunk*)(t->prev())); + i = t->MChunk::last_index(); + } + set_cache(t); + return i; +} + + +int MPlex::dosucc(int idx) const +{ + if (idx < lo) idx = lo; + if (idx >= fnc - 1) return fnc; + + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int i = t->MChunk::succ(idx); + while (i >= t->fence_index() && i < fnc) + { + t = (MChunk*)(t->next()); + i = t->MChunk::first_index(); + } + set_cache(t); + return i; +} + +void MPlex::prev(Pix& i) const +{ + if (i == 0) return; + + * p = (*) i; + const MChunk* old = ch; + const MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->prev())); + if (t == old) + { + i = 0; + return; + } + } + * q = t->MChunk::pred(p); + while (q == 0 && t != (MChunk*)hd) + { + t = ((MChunk*)(t->prev())); + q = t->MChunk::last_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + +void MPlex::next(Pix& i) const +{ + if (i == 0) return; + + * p = (*) i; + const MChunk* tail = (MChunk*)(tl()); + const MChunk* old = ch; + const MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) + { + i = 0; + return; + } + } + * q = t->MChunk::succ(p); + while (q == 0 && t != tail) + { + t = ((MChunk*)(t->next())); + q = t->MChunk::first_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + + +void MPlex::undel_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + + MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int was_present = t->MChunk::undel(idx); + if (!was_present) + { + --unused; + } + set_cache(t); + return; +} + +void MPlex::clear() +{ + if (fnc != lo) + { + MChunk* t = ((MChunk*)tl()); + while (t != hd) + { + MChunk* prv = (MChunk*)(t->prev()); + del_chunk(t); + t = prv; + } + t->MChunk::clear(lo); + set_cache(t); + fnc = lo; + unused = 0; + } +} + +int MPlex::OK () const +{ + int v = hd != 0; // at least one chunk + + int found_ch = 0; // to make sure ch is in list; + + int count = 0; // to count unused slots + + const MChunk* t = (MChunk*)(hd); + + int gap = t->low_index() - lo; + v &= gap == 0; // hd lo not less than lo. + count += gap; + + for (;;) + { + if (t == ch) ++found_ch; + v &= t->MChunk::OK(); // each chunk is OK + count += t->unused_indices(); + if (t == (MChunk*)(tl())) + break; + else // and has indices less than succ + { + gap = t->next()->base_index() - t->top_index(); + v &= gap == 0; + count += gap; + + if (t != (MChunk*)hd) // internal chunks can't grow + v &= !t->can_grow_low() && !t->can_grow_high(); + + t = (const MChunk*)(t->next()); + } + } + gap = fnc - t->fence_index(); + v &= gap == 0; + count += gap; + + v &= count == unused; // chunk counts agree with plex + + v &= found_ch == 1; + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/MPlex.hP b/gnu/lib/libg++/g++-include/MPlex.hP new file mode 100644 index 0000000000..8bf78d13a1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/MPlex.hP @@ -0,0 +1,414 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _MPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _MPlex_h 1 + + +#include ".Plex.h" + + +// Number of bits per long, used in MChunk bit map operations + +#define _MAP_BITS 32 + + +class MChunk : public IChunk +{ +protected: + + unsigned long* map; // bitmap of slots + int unused; // number of unused internal slots + + void mark(int); // bitmap operations + void free(int); + int valid(int) const; + +public: + + MChunk(* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, // & initially clear map + int fence_idx, + int top_idx); + + ~MChunk(); + +// virtuals + + int first_index() const; + int last_index() const; + int succ(int idx) const; + int pred(int idx) const; + * first_pointer() const; + * last_pointer() const; + * succ(*) const; + * pred(*) const; + int empty() const; + int full() const; + int valid_index(int i) const; + int valid_pointer(const * p) const; + * grow_high (); + * grow_low (); + void shrink_high (); + void shrink_low (); + void clear(int); + void cleardown(int); + int OK() const; + +// extensions + + int unused_indices() const; // how many free slot in low..fence? + + int unused_index() const; // return index of free slot + + int del(int i); // delete data indexed by i + // return true if was present + int undel(int idx); // un-delete data indexed by i + // return true if already present + + void reset_low(); // reset low = lowest valid index; + void reset_high(); // same for high + +}; + + +class MPlex: public Plex +{ + MChunk* ch; // cached chunk + int unused; // # of free slots between low & fence + + void make_initial_chunks(int up = 1); + void cache(int idx) const; + void cache(const * p) const; + int dopred(int) const; + int dosucc(int) const; + + void set_cache(const MChunk* t) const; // logically, + // not physically const + +public: + MPlex(); // set low = 0; + // fence = 0; + // csize = default + + MPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + MPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + MPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + MPlex(const MPlex&); + + void operator= (const MPlex&); + +// virtuals + + & high_element (); + & low_element (); + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const ; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + void clear(); + + int OK () const; + +// extensions + + int count() const; // # valid elements + int available() const; // # deleted elements + + int unused_index()const; // return index of a deleted elem + Pix unused_Pix() const; // return Pix of a deleted elem + + int del_index(int idx); // logically delete at idx; + // return true if was present + int del_Pix(Pix p); // delete at p + + void undel_index(int idx); // undelete at idx; + void undel_Pix(Pix p); // undelete at p; + + void adjust_bounds(); // reset lo, hi to lowest & + // highest valid indices + + int add(const elem); // add anywhere +}; + + +inline MChunk:: ~MChunk() +{ + delete map; +} + +inline void MChunk::mark(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] |= 1 << (i & (_MAP_BITS - 1)); +} + +inline void MChunk::free(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] &= ~(1 << (i & (_MAP_BITS - 1))); +} + +inline int MChunk::valid(int idx) const +{ + unsigned int i = idx - base; + return map[i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1))); +} + +inline int MChunk:: valid_index(int i) const +{ + return i >= low && i < fence && valid(i); +} + +inline int MChunk:: valid_pointer(const * p) const +{ + int i = ((int)p - (int)data) / sizeof(); + return i >= 0 && i < (fence - base) && + (map[(unsigned)i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1)))); +} + +inline int MChunk::empty() const +{ + return fence - low - unused == 0; +} + +inline int MChunk::full() const +{ + return unused + (top - fence) + (low - base) == 0; +} + +inline int MChunk::succ(int idx) const +{ + int i = (idx < low)? low : idx + 1; + while (i < fence && !valid(i)) ++i; + return i; +} + +inline int MChunk::pred(int idx) const +{ + int i = (idx > fence)? (fence - 1) : idx - 1; + while (i >= low && !valid(i)) --i; + return i; +} + +inline int MChunk::unused_indices() const +{ + return unused; +} + +inline * MChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + mark(fence); + return &(data[fence++ - base]); +} + +inline * MChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + mark(--low); + return &(data[low - base]); +} + +inline void MChunk::reset_low() +{ + while (low < fence && !valid(low)) + { + --unused; + ++low; + } +} + +inline void MChunk::reset_high() +{ + while (fence > low && !valid(fence - 1)) + { + --unused; + --fence; + } +} + +inline int MPlex::full () const +{ + return 0; +} + +inline int MPlex::can_add_high() const +{ + return 1; +} + +inline int MPlex::can_add_low() const +{ + return 1; +} + +inline int MPlex::available() const +{ + return unused; +} + +inline int MPlex::count() const +{ + return fnc - lo - unused; +} + +inline void MPlex::set_cache(const MChunk* t) const +{ + ((MPlex*)(this))->ch = (MChunk*)t; +} + +inline & MPlex:: operator [] (int idx) +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return * (ch->pointer_to(idx)); +} + +inline const & MPlex:: operator [] (int idx) const +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return * ((const *)(ch->pointer_to(idx))); +} + +inline int MPlex::Pix_to_index(Pix p) const +{ + if (!ch->MChunk::valid_pointer((*)p)) cache((*)p); + return ch->index_of((*)p); +} + +inline int MPlex::high() const +{ + return (((const MChunk*)tl())->MChunk::valid_index(fnc-1)) ? + fnc-1 : dopred(fnc-1); +} + +inline int MPlex::low() const +{ + return (((const MChunk*)hd)->MChunk::valid_index(lo))? lo : dosucc(lo); +} + +inline & MPlex::low_element () +{ + return (*this)[low()]; +} + +inline const & MPlex::low_element () const +{ + return (*this)[low()]; +} + +inline & MPlex::high_element () +{ + return (*this)[high()]; +} + +inline const & MPlex::high_element () const +{ + return (*this)[high()]; +} + +inline Pix MPlex::index_to_Pix(int idx) const +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return Pix(ch->pointer_to(idx)); +} + +inline void MPlex::next(int& idx) const +{ + idx = (ch->MChunk::valid_index(idx+1))? idx+1 : dosucc(idx); +} + +inline void MPlex::prev(int& idx) const +{ + idx = (ch->MChunk::valid_index(idx-1))? idx-1 : dopred(idx); +} + +inline Pix MPlex::first() const +{ + return index_to_Pix(low()); +} + +inline Pix MPlex::last() const +{ + return index_to_Pix(high()); +} + + +inline void MPlex::undel_Pix(Pix p) +{ + undel_index(Pix_to_index(p)); +} + +inline int MPlex::del_Pix(Pix p) +{ + return del_index(Pix_to_index(p)); +} + +inline & MPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline const & MPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Map.ccP b/gnu/lib/libg++/g++-include/Map.ccP new file mode 100644 index 0000000000..03bb4b84f0 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Map.ccP @@ -0,0 +1,58 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..Map.h" + + +Pix Map::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ(key(i), item)); next(i)); + return i; +} + +int Map::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void Map::clear() +{ + Pix i = first(); + while (i != 0) + { + del(key(i)); + i = first(); + } +} + +int Map::contains ( item) +{ + return seek(item) != 0; +} + + +void Map::error(const char* msg) +{ + (*lib_error_handler)("Map", msg); +} diff --git a/gnu/lib/libg++/g++-include/Map.hP b/gnu/lib/libg++/g++-include/Map.hP new file mode 100644 index 0000000000..716a17fdd9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Map.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Map_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Map_h 1 + +#include +#include ".defs.h" + +class Map +{ +protected: + int count; + def; + +public: + Map( dflt); + virtual ~Map(); + + int length(); // current number of items + int empty(); + + virtual int contains( key); // is key mapped? + + virtual void clear(); // delete all items + + virtual & operator [] ( key) = 0; // access contents by key + + virtual void del( key) = 0; // delete entry + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & key(Pix i) = 0; // access key at i + virtual & contents(Pix i) = 0; // access contents at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( key); // Pix of key + + & dflt(); // access default val + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline Map::~Map() {} + +inline int Map::length() +{ + return count; +} + +inline int Map::empty() +{ + return count == 0; +} + +inline & Map::dflt() +{ + return def; +} + +inline Map::Map( dflt) :def(dflt) +{ + count = 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/OSLBag.ccP b/gnu/lib/libg++/g++-include/OSLBag.ccP new file mode 100644 index 0000000000..78398192bc --- /dev/null +++ b/gnu/lib/libg++/g++-include/OSLBag.ccP @@ -0,0 +1,196 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OSLBag.h" + + +Pix OSLBag::seek( item, Pix i) +{ + if (i == 0) i = p.first(); else next(i); + for (; i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +int OSLBag::nof( item) +{ + int n = 0; + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + ++n; + else if (cmp < 0) + break; + } + return n; +} + +Pix OSLBag::add( item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLBag::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLBag::remove( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_front(); + i = p.first(); + } while (i != 0 && EQ(item, p(i))); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_after(trail); + i = trail; + next(i); + } while (i != 0 && EQ(item, p(i))); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +int OSLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= CMP(p(trail), p(i)) <= 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/OSLBag.hP b/gnu/lib/libg++/g++-include/OSLBag.hP new file mode 100644 index 0000000000..de4d67cf9a --- /dev/null +++ b/gnu/lib/libg++/g++-include/OSLBag.hP @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OSLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OSLBag_h 1 + +#include ".Bag.h" +#include ".SLList.h" + +class OSLBag : public Bag +{ +protected: + SLList p; + +public: + OSLBag(); + OSLBag(const OSLBag&); + + Pix add( item); + void del( item); + void remove(item); + + int contains( item); + int nof( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline OSLBag::OSLBag() : p() { count = 0; } + +inline OSLBag::OSLBag(const OSLBag& s) : p(s.p) { count = s.count; } + +inline Pix OSLBag::first() +{ + return p.first(); +} + +inline void OSLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & OSLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OSLBag::clear() +{ + count = 0; p.clear(); +} + +inline int OSLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OSLBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/OSLSet.ccP b/gnu/lib/libg++/g++-include/OSLSet.ccP new file mode 100644 index 0000000000..bfd32ae954 --- /dev/null +++ b/gnu/lib/libg++/g++-include/OSLSet.ccP @@ -0,0 +1,321 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OSLSet.h" + + +Pix OSLSet::seek( item) +{ + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +Pix OSLSet::add( item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLSet::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + + +int OSLSet::operator <= (OSLSet& b) +{ + if (count > b.count) return 0; + Pix i = first(); + Pix j = b.first(); + for (;;) + { + if (i == 0) + return 1; + else if (j == 0) + return 0; + int cmp = CMP(p(i), b.p(j)); + if (cmp == 0) + { + next(i); b.next(j); + } + else if (cmp < 0) + return 0; + else + b.next(j); + } +} + +int OSLSet::operator == (OSLSet& b) +{ + if (count != b.count) return 0; + if (count == 0) return 1; + Pix i = p.first(); + Pix j = b.p.first(); + while (i != 0) + { + if (!EQ(p(i),b.p(j))) return 0; + next(i); + b.next(j); + } + return 1; +} + + +void OSLSet::operator |= (OSLSet& b) +{ + if (&b == this || b.count == 0) + return; + else + { + Pix j = b.p.first(); + Pix i = p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0) + return; + else if (i == 0) + { + for (; j != 0; b.next(j)) + { + ++count; + p.append(b.p(j)); + } + return; + } + int cmp = CMP(p(i), b.p(j)); + if (cmp <= 0) + { + if (cmp == 0) b.next(j); + trail = i; + next(i); + } + else + { + ++count; + if (trail == 0) + trail = p.prepend(b.p(j)); + else + trail = p.ins_after(trail, b.p(j)); + b.next(j); + } + } + } +} + + +void OSLSet::operator -= (OSLSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0 || i == 0) + return; + int cmp = CMP(p(i), b.p(j)); + if (cmp == 0) + { + --count; + b.next(j); + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else if (cmp < 0) + { + trail = i; + next(i); + } + else + b.next(j); + } + } +} + +void OSLSet::operator &= (OSLSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (i == 0) + return; + else if (j == 0) + { + if (trail == 0) + { + p.clear(); + count = 0; + } + else + { + while (i != 0) + { + --count; + next(i); + p.del_after(trail); + } + } + return; + } + int cmp = CMP(p(i), b.p(j)); + + if (cmp == 0) + { + trail = i; + next(i); + b.next(j); + } + else if (cmp < 0) + { + --count; + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else + b.next(j); + } + } +} + + +int OSLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= CMP(p(trail), p(i)) < 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/OSLSet.hP b/gnu/lib/libg++/g++-include/OSLSet.hP new file mode 100644 index 0000000000..bf3707f6c7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/OSLSet.hP @@ -0,0 +1,101 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OSLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OSLSet_h 1 + +#include ".Set.h" +#include ".SLList.h" + +class OSLSet : public Set +{ +protected: + SLList p; + +public: + OSLSet(); + OSLSet(const OSLSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + void operator |= (OSLSet& b); + void operator -= (OSLSet& b); + void operator &= (OSLSet& b); + + int operator == (OSLSet& b); + int operator != (OSLSet& b); + int operator <= (OSLSet& b); + + int OK(); +}; + + +inline OSLSet::OSLSet() : p() { count = 0; } + +inline OSLSet::OSLSet(const OSLSet& s) : p(s.p) { count = s.count; } + +inline Pix OSLSet::first() +{ + return p.first(); +} + +inline void OSLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & OSLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OSLSet::clear() +{ + count = 0; p.clear(); +} + +inline int OSLSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int OSLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OSLSet::operator != (OSLSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/OXPBag.ccP b/gnu/lib/libg++/g++-include/OXPBag.ccP new file mode 100644 index 0000000000..6619e25ea1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/OXPBag.ccP @@ -0,0 +1,221 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OXPBag.h" + + +Pix OXPBag::seek( item, Pix i) +{ + if (i == 0) + { + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > p.low() && EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + int cmp = CMP(item, p(i)); + if (cmp == 0) + { + next(i); + return (EQ(item, p(i)))? i : 0; + } + else if (cmp < 0) + { + int ind = p.Pix_to_index(i); + int l = ind; + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + cmp = CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > ind && EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + else + return 0; +} + +int OXPBag::nof( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && EQ(item, p[l - 1])) --l; + while (h < p.high() && EQ(item, p[h + 1])) ++h; + return h - l + 1; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix OXPBag::add( item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = mid; + break; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.high() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void OXPBag::del( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +void OXPBag::remove( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && EQ(item, p[l - 1])) --l; + while (h < p.high() && EQ(item, p[h + 1])) ++h; + int n = h - l + 1; + count -= n; + if (p.high() - h < l - p.low()) + { + h = p.high() - n; + for (int i = l; i <= h; ++i) p[i] = p[i+n]; + while (n-- > 0) p.del_high(); + } + else + { + l = p.low() + n; + for (int i = h; i >= l; --i) p[i] = p[i-n]; + while (n-- > 0) p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int OXPBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= CMP(p[i], p[i+1]) <= 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/OXPBag.hP b/gnu/lib/libg++/g++-include/OXPBag.hP new file mode 100644 index 0000000000..128d4a20e4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/OXPBag.hP @@ -0,0 +1,73 @@ +#ifndef _OXPBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OXPBag_h 1 + +#include ".Bag.h" +#include ".XPlex.h" + +class OXPBag : public Bag +{ +protected: + XPlex p; + +public: + OXPBag(int chunksize = DEFAULT_INITIAL_CAPACITY); + OXPBag(const OXPBag&); + + Pix add( item); + void del( item); +#undef remove + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline OXPBag::OXPBag(int chunksize) + : p(chunksize) { count = 0; } + +inline OXPBag::OXPBag(const OXPBag& s) : p(s.p) { count = s.count; } + +inline Pix OXPBag::first() +{ + return p.first(); +} + +inline void OXPBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & OXPBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OXPBag::clear() +{ + count = 0; p.clear(); +} + +inline int OXPBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OXPBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/OXPSet.ccP b/gnu/lib/libg++/g++-include/OXPSet.ccP new file mode 100644 index 0000000000..1461195451 --- /dev/null +++ b/gnu/lib/libg++/g++-include/OXPSet.ccP @@ -0,0 +1,280 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OXPSet.h" + + +Pix OXPSet::seek( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix OXPSet::add( item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.fence() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void OXPSet::del( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int OXPSet::operator <= (OXPSet& b) +{ + if (count > b.count) return 0; + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i >= p.fence()) + return 1; + else if (j >= b.p.fence()) + return 0; + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + return 0; + else + ++j; + } +} + +int OXPSet::operator == (OXPSet& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + int i = p.low(); + int j = b.p.low(); + while (n-- > 0) if (!EQ(p[i++], b.p[j++])) return 0; + return 1; +} + + +void OXPSet::operator |= (OXPSet& b) +{ + if (&b == this || b.count == 0) + return; + else if (b.count <= 2) // small b -- just add + for (Pix i = b.first(); i; b.next(i)) add(b(i)); + else + { + // strategy: merge into top of p, simultaneously killing old bottom + int oldfence = p.fence(); + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i == oldfence) + { + while (j < b.p.fence()) p.add_high(b.p[j++]); + break; + } + else if (j == b.p.fence()) + { + while (i++ < oldfence) + { + p.add_high(p.low_element()); + p.del_low(); + } + break; + } + int cmp = CMP(p[i], b.p[j]); + if (cmp <= 0) + { + ++i; + if (cmp == 0) ++j; + p.add_high(p.low_element()); + p.del_low(); + } + else + p.add_high(b.p[j++]); + } + count = p.length(); + } +} + + + +void OXPSet::operator -= (OXPSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence) + break; + else if (j >= b.p.fence()) + { + if (k != i) + while (i < oldfence) p[k++] = p[i++]; + else + k = oldfence; + break; + } + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; + } + else + j++; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +void OXPSet::operator &= (OXPSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence || j >= b.p.fence()) + break; + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; ++j; + } + else if (cmp < 0) + ++i; + else + ++j; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +int OXPSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= CMP(p[i], p[i+1]) < 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/OXPSet.hP b/gnu/lib/libg++/g++-include/OXPSet.hP new file mode 100644 index 0000000000..4e0c97712d --- /dev/null +++ b/gnu/lib/libg++/g++-include/OXPSet.hP @@ -0,0 +1,102 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OXPSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OXPSet_h 1 + +#include ".Set.h" +#include ".XPlex.h" + +class OXPSet : public Set +{ +protected: + XPlex p; + +public: + OXPSet(int chunksize = DEFAULT_INITIAL_CAPACITY); + OXPSet(const OXPSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + void operator |= (OXPSet& b); + void operator -= (OXPSet& b); + void operator &= (OXPSet& b); + + int operator == (OXPSet& b); + int operator != (OXPSet& b); + int operator <= (OXPSet& b); + + int OK(); +}; + + +inline OXPSet::OXPSet(int chunksize) + : p(chunksize) { count = 0; } + +inline OXPSet::OXPSet(const OXPSet& s) : p(s.p) { count = s.count; } + +inline Pix OXPSet::first() +{ + return p.first(); +} + +inline void OXPSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & OXPSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OXPSet::clear() +{ + count = 0; p.clear(); +} + +inline int OXPSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int OXPSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OXPSet::operator != (OXPSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/PHPQ.ccP b/gnu/lib/libg++/g++-include/PHPQ.ccP new file mode 100644 index 0000000000..764b11c5cf --- /dev/null +++ b/gnu/lib/libg++/g++-include/PHPQ.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".PHPQ.h" + +// +// This defines a Pairing Heap structure +// +// See ``The Pairing Heap: A New Form of Self-Adjusting Heap'' +// Fredman, Segdewick et al, +// Algorithmica (1986) 1:111-129 +// +// In particular, this implements the pairing heap using the circular +// list. +// +// + +PHPQ::PHPQ(int sz) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(sz); +} + +PHPQ::PHPQ(PHPQ& a) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(a.size); + for (Pix i = a.first(); i != 0; a.next(i)) enq(a(i)); +} + + +void PHPQ::prealloc(int newsize) +{ + ++newsize; // leave a spot for freelist + if (size != 0) + { + int news = size; + while (news <= newsize) news = (news * 3) / 2; + newsize = news; + } + // see if indices are OK + PHPQNode test; + test.sibling = 0; + test.sibling = ~test.sibling; + if ((unsigned long)newsize > (unsigned long)(test.sibling)) + error("storage size exceeds index range"); + + if (storage == 0) + { + storage = new PHPQNode[size = newsize]; + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + } + else + { + PHPQNode* newstor = new PHPQNode[newsize]; + for (int i = 1; i < size; ++i) + newstor[i] = storage[i]; + delete [] storage; + storage = newstor; + for (i = size; i < newsize; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[newsize-1].sibling = 0; + storage[0].sibling = size; + size = newsize; + } +} + + +void PHPQ::clear() +{ + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + root = 0; + count = 0; +} + +Pix PHPQ::enq( item) +{ + ++count; + if (storage[0].sibling == 0) + prealloc(count); + + int cell = storage[0].sibling; + storage[0].sibling = storage[cell].sibling; + storage[cell].sibling = 0; + storage[cell].children = 0; + storage[cell].item = item; + storage[cell].valid = 1; + + if (root == 0) + { + root = cell; + return Pix(root); + } + else + { + int parent; + int child; + + if (LE(storage[root].item, storage[cell].item)) + { + parent = root; child = cell; + } + else + { + parent = cell; child = root; + } + int popsKid = storage[parent].children; + + if (popsKid == 0) + { + storage[parent].children = child; + storage[child].sibling = child; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = child; + storage[child].sibling = temp; + storage[parent].children = child; + } + root = parent; + return Pix(cell); + } +} + +// +// Item removal is the most complicated routine. +// +// We remove the root (should there be one) and then select a new +// root. The siblings of the root are in a circular list. We continue +// to pair elements in this list until there is a single element. +// This element will be the new root. + +void PHPQ::del_front() +{ + int valid = 0; + do + { + if (root == 0) return; + if (valid = storage[root].valid) + --count; + storage[root].valid = 0; + int child = storage[root].children; + storage[root].sibling = storage[0].sibling; + storage[0].sibling = root; + + if (child == 0) + { + root = 0; + return; + } + else + { + while(storage[child].sibling != child) + { + // We have at least two kids, but we may only have + // two kids. So, oneChild != child, but it is possible + // that twoChild == child. + + int oneChild = storage[child].sibling; + int twoChild = storage[oneChild].sibling; + + // Remove the two from the sibling list + + storage[child].sibling = storage[twoChild].sibling; + storage[oneChild].sibling = 0; + storage[twoChild].sibling = 0; + + int bestChild; + int worstChild; + + if (LE(storage[oneChild].item, storage[twoChild].item)) + { + bestChild = oneChild; worstChild = twoChild; + } + else + { + bestChild = twoChild; worstChild = oneChild; + } + int popsKid = storage[bestChild].children; + + if (popsKid == 0) + { + storage[bestChild].children = worstChild; + storage[worstChild].sibling = worstChild; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = worstChild; + storage[worstChild].sibling = temp; + storage[bestChild].children = worstChild; + } + if (twoChild == child) + { + // We have reduced the two to one, so we'll be exiting. + child = bestChild; + storage[child].sibling = child; + } + else + { + // We've removed two siblings, now we need to insert + // the better of the two + storage[bestChild].sibling = storage[child].sibling; + storage[child].sibling = bestChild; + child = storage[bestChild].sibling; + } + } + root = child; + } + } while ( !valid ); +} + +void PHPQ::del(Pix p) +{ + if (p == 0) error("null Pix"); + int i = int(p); + if (storage[i].valid) + { + if (i == root) + del_front(); + else + { + storage[i].valid = 0; + --count; + } + } +} + + +Pix PHPQ::seek( key) +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid && EQ(storage[i].item, key)) + return Pix(i); + return 0; +} + +Pix PHPQ::first() +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid) + return Pix(i); + return 0; +} + + +void PHPQ::next(Pix& p) +{ + if (p == 0) return; + for (int i = int(p)+1; i < size; ++i) + if (storage[i].valid) + { + p = Pix(i); + return; + } + p = 0; +} + +int PHPQ::OK() +{ + int v = storage != 0; + int n = 0; + for (int i = 0; i < size; ++i) if (storage[i].valid) ++n; + v &= n == count; + v &= check_sibling_list(root); + int ct = MAXLONG; + n = 0; + int f = storage[0].sibling; + while (f != 0 && ct-- > 0) + { + f = storage[f].sibling; + ++n; + } + v &= ct > 0; + v &= n <= size - count; + if (!v) error("invariant failure"); + return v; +} + + +int PHPQ::check_sibling_list(int t) +{ + if (t != 0) + { + int s = t; + long ct = MAXLONG; // Lots of chances to find self! + do + { + if (storage[s].valid && !check_sibling_list(storage[s].children)) + return 0; + s = storage[s].sibling; + } while (ct-- > 0 && s != t && s != 0); + if (ct <= 0) return 0; + } + return 1; +} + + diff --git a/gnu/lib/libg++/g++-include/PHPQ.hP b/gnu/lib/libg++/g++-include/PHPQ.hP new file mode 100644 index 0000000000..359c527c60 --- /dev/null +++ b/gnu/lib/libg++/g++-include/PHPQ.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef PHPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define PHPQ_h 1 + +#include ".PQ.h" + +#ifndef PHPQIndex +#define PHPQIndex unsigned short +#endif + +struct PHPQNode +{ + PHPQIndex sibling; + PHPQIndex children; + item; + char valid; +}; + + +class PHPQ : public PQ +{ + PHPQNode* storage; // table -- freelist in storage[0].sibling + int root; + int size; + + void prealloc(int); + int check_sibling_list(int); + +public: + + PHPQ(int sz = DEFAULT_INITIAL_CAPACITY); + PHPQ(PHPQ&); + ~PHPQ(); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + void del(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + + +inline PHPQ::~PHPQ() +{ + delete [] storage; +} + + +inline PHPQ::deq() +{ + if (count == 0) error("deq of empty PQ"); + x = storage[root].item; + del_front(); + return x; +} + + +inline & PHPQ::front() +{ + if (count == 0) error("front of empty PQ"); + return storage[root].item; +} + +inline int PHPQ::contains( item) +{ + return seek(item) != 0; +} + +inline & PHPQ::operator() (Pix p) +{ + if (p == 0) error("null Pix"); + return storage[int(p)].item; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/PQ.ccP b/gnu/lib/libg++/g++-include/PQ.ccP new file mode 100644 index 0000000000..810240759c --- /dev/null +++ b/gnu/lib/libg++/g++-include/PQ.ccP @@ -0,0 +1,62 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".PQ.h" + + + + PQ::deq() +{ + x = front(); + del_front(); + return x; +} + +Pix PQ::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ((*this)(i), item)); next(i)); + return i; +} + +int PQ::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void PQ::clear() +{ + while (count != 0) del_front(); +} + +int PQ::contains ( item) +{ + return seek(item) != 0; +} + + +void PQ::error(const char* msg) +{ + (*lib_error_handler)("PQ", msg); +} + diff --git a/gnu/lib/libg++/g++-include/PQ.hP b/gnu/lib/libg++/g++-include/PQ.hP new file mode 100644 index 0000000000..981592ae85 --- /dev/null +++ b/gnu/lib/libg++/g++-include/PQ.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _PQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _PQ_h 1 + +#include +#include ".defs.h" + +class PQ +{ +protected: + + int count; + +public: + PQ(); + virtual ~PQ(); + + int length(); // current number of items + int empty(); + + virtual Pix enq( item) = 0; // add item; return Pix + virtual deq(); // return & remove min + + virtual & front() = 0; // access min item + virtual void del_front() = 0; // delete min item + + virtual int contains( item); // is item in PQ? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & operator () (Pix i) = 0; // access item at i + virtual void del(Pix i) = 0; // delete item at i + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( item); // Pix of item + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline PQ::PQ() :count(0) {} + +inline PQ::~PQ() {} + +inline int PQ::length() +{ + return count; +} + +inline int PQ::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/PSList.hP b/gnu/lib/libg++/g++-include/PSList.hP new file mode 100644 index 0000000000..eacb34dbe3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/PSList.hP @@ -0,0 +1,32 @@ +/* : Light weight list: This will simply reuse code from a VoidP List, which +was genclassed from the SLList libg++ class. The classes generated from this file +will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not +offer all the functionality of List classes, such as sharing of sub-lists. +However, no additional code is needed at all and no .cc file is generated. So it costs nothing +to use these type-safe lists. Only member functions needing type casting are re-defined */ + + +#ifndef _SList_h +#define _SList_h 1 + +#include "VoidP.SLList.h" +#include ".defs.h" + +class SList : public VoidPSLList +{ +public: + SList() {} + SList(SList& a) : (a) {} + ~SList() {} + + SList& operator = (SList& a) { + return (SList&) VoidPSLList::operator= (a); } + + & operator () (Pix p) { return (&) (VoidPSLList::operator() (p)); } + & front() { return (&) VoidPSLList::front(); } + & rear() { return (&) VoidPSLList::rear(); } + remove_front() { return () VoidPSLList::remove_front(); } + +}; + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/PVec.hP b/gnu/lib/libg++/g++-include/PVec.hP new file mode 100644 index 0000000000..de32482610 --- /dev/null +++ b/gnu/lib/libg++/g++-include/PVec.hP @@ -0,0 +1,79 @@ +/* : light weight Vector: This will simply reuse code from */ +/* a VoidP Vec, which was genclassed from the Vec libg++ class. */ +/* The classes generated from this file will all be derived classes */ +/* from class VoidVec or intVec. No .cc file is generated. So */ +/* it costs nothing to use these type-safe Vectors. Only member */ +/* functions needing type casting are re-defined. */ +/* */ + +#ifndef _Vec_h +#define _Vec_h 1 + +#include "VoidP.Vec.h" +#include ".defs.h" + + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)( ); +typedef (*Mapper)( ); +typedef (*Combiner)( , ); +typedef int (*Predicate)( ); +typedef int (*Comparator)( , ); +#endif + +class Vec : public VoidPVec +{ +protected: + Vec(int l, * d) : (l, (VoidP*) d) {}; +public: + Vec() {}; + Vec(int l) : (l) {}; + Vec(int l, fill_value) : (l, fill_value) {}; + Vec(Vec& v) : (v) {}; + Vec(VoidPVec& v) {fake_copy(v, s, len);} + ~Vec() {}; + + Vec& operator = (Vec& a) + {return (Vec&) VoidPVec::operator= (a);} + Vec at(int from, int n) {return (Vec) VoidPVec::at(from, n);} + + & operator [] (int n) {return (&)VoidPVec::operator[] (n);} + & elem(int n) {return (&)VoidPVec::elem(n);} + + friend Vec concat(Vec& a, Vec& b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec& a); + + void sort(Comparator f); + void apply(Procedure f); + reduce(Combiner f, base); +}; + +inline Vec concat(Vec& a, Vec& b) +{return (Vec)concat((VoidPVec&)a, (VoidPVec&)b);} + +inline Vec map(Mapper f, Vec & a) { + return (Vec)map((VoidPMapper)f, (VoidPVec&)a); } + +inline Vec merge(Vec & a, Vec & b, Comparator f) { + return (Vec)merge((VoidPVec&)a, (VoidPVec&)b, (VoidPComparator)f); } + +inline Vec combine(Combiner f, Vec & a, Vec & b) { + return (Vec)combine((VoidPCombiner)f, (VoidPVec&)a, (VoidPVec&)b); } + +inline Vec reverse(Vec& a) { + return (Vec)reverse((VoidPVec&)a);} + +inline void Vec::sort(Comparator f) { + VoidPVec::sort((VoidPComparator) f); } + +inline void Vec::apply(Procedure f) { + VoidPVec::apply((VoidPProcedure) f); } + +inline Vec::reduce(Combiner f, base) { + return ()VoidPVec::reduce((VoidPCombiner)f, base);} + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/Plex.ccP b/gnu/lib/libg++/g++-include/Plex.ccP new file mode 100644 index 0000000000..5eb13c85f4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Plex.ccP @@ -0,0 +1,222 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".Plex.h" + +// IChunk support + +void IChunk::error(const char* msg) const +{ + (*lib_error_handler)("IChunk", msg); +} + +void IChunk::index_error() const +{ + error("attempt to use invalid index"); +} + +void IChunk::empty_error() const +{ + error("invalid use of empty chunk"); +} + +void IChunk::full_error() const +{ + error("attempt to extend chunk beyond bounds"); +} + +IChunk:: ~IChunk() {} + +IChunk::IChunk(* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) +{ + if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx) + error("inconsistent specification"); + data = d; + base = baseidx; + low = lowidx; + fence = fenceidx; + top = topidx; + nxt = prv = this; +} + +void IChunk:: re_index(int lo) +{ + int delta = lo - low; + base += delta; + low += delta; + fence += delta; + top += delta; +} + + +void IChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; +} + +void IChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; +} + +int IChunk:: OK() const +{ + int v = data != 0; // have some data + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= nxt->prv == this; // and links are OK + v &= prv->nxt == this; + if (!v) error("invariant failure"); + return(v); +} + + +// error handling + + +void Plex::error(const char* msg) const +{ + (*lib_error_handler)("Plex", msg); +} + +void Plex::index_error() const +{ + error("attempt to access invalid index"); +} + +void Plex::empty_error() const +{ + error("attempted operation on empty plex"); +} + +void Plex::full_error() const +{ + error("attempt to increase size of plex past limit"); +} + +// generic plex ops + +Plex:: ~Plex() +{ + invalidate(); +} + + +void Plex::append (const Plex& a) +{ + for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]); +} + +void Plex::prepend (const Plex& a) +{ + for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]); +} + +void Plex::reverse() +{ + tmp; + int l = low(); + int h = high(); + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + + +void Plex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void Plex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void Plex::del_chunk(IChunk* x) +{ + if (x != 0) + { + x->unlink(); + * data = (*)(x->invalidate()); + delete [] data; + delete x; + } +} + + +void Plex::invalidate() +{ + IChunk* t = hd; + if (t != 0) + { + IChunk* tail = tl(); + while (t != tail) + { + IChunk* nxt = t->next(); + del_chunk(t); + t = nxt; + } + del_chunk(t); + hd = 0; + } +} + +int Plex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + return old; +} + + + + diff --git a/gnu/lib/libg++/g++-include/Plex.hP b/gnu/lib/libg++/g++-include/Plex.hP new file mode 100644 index 0000000000..f8af1b6ba7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Plex.hP @@ -0,0 +1,494 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _Plex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Plex_h 1 + +#include +#include +#include ".defs.h" + +// Plexes are made out of IChunks + +#include + +class IChunk +{ +//public: // kludge until C++ `protected' policies settled +protected: + + * data; // data, from client + + int base; // lowest possible index + int low; // lowest valid index + int fence; // highest valid index + 1 + int top; // highest possible index + 1 + + IChunk* nxt; // circular links + IChunk* prv; + +public: + +// constructors + + IChunk(* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, + int fence_idx, + int top_idx); + + virtual ~IChunk(); + +// status reports + + int size() const; // number of slots + + virtual int empty() const ; + virtual int full() const ; + + int can_grow_high () const ; // there is space to add data + int can_grow_low () const; + + int base_index() const; // lowest possible index; + int low_index() const; // lowest actual index; + virtual int first_index() const; // lowest valid index or fence if none + virtual int last_index() const; // highest valid index or low-1 if none + int fence_index() const; // highest actual index + 1 + int top_index() const; // highest possible index + 1 + +// indexing conversion + + int possible_index(int i) const; // i between base and top + int actual_index(int i) const; // i between low and fence + virtual int valid_index(int i) const; // i not deleted (mainly for mchunks) + + int possible_pointer(const * p) const; // same for ptr + int actual_pointer(const * p) const; + virtual int valid_pointer(const * p) const; + + * pointer_to(int i) const ; // pointer to data indexed by i + // caution: i is not checked for validity + int index_of(const * p) const; // index of data pointed to by p + // caution: p is not checked for validity + + virtual int succ(int idx) const; // next valid index or fence if none + virtual int pred(int idx) const; // previous index or low - 1 if none + + virtual * first_pointer() const; // pointer to first valid pos or 0 + virtual * last_pointer() const; // pointer to first valid pos or 0 + virtual * succ(* p) const; // next pointer or 0 + virtual * pred(* p) const; // previous pointer or 0 + +// modification + + virtual * grow_high (); // return spot to add an element + virtual * grow_low (); + + virtual void shrink_high (); // logically delete top index + virtual void shrink_low (); + + virtual void clear(int lo); // reset to empty ch with base = lo + virtual void cleardown(int hi); // reset to empty ch with top = hi + void re_index(int lo); // re-index so lo is new low + +// chunk traversal + + IChunk* next() const; + IChunk* prev() const; + + void link_to_prev(IChunk* prev); + void link_to_next(IChunk* next); + void unlink(); + +// state checks + + * invalidate(); // mark self as invalid; return data + // for possible deletion + + virtual int OK() const; // representation invariant + + void error(const char*) const; + void empty_error() const; + void full_error() const; + void index_error() const; +}; + +// Plex is a partly `abstract' class: few of the virtuals +// are implemented at the Plex level, only in the subclasses + +class Plex +{ +protected: + + IChunk* hd; // a chunk holding the data + int lo; // lowest index + int fnc; // highest index + 1 + int csize; // size of the chunk + + void invalidate(); // mark so OK() is false + void del_chunk(IChunk*); // delete a chunk + + IChunk* tl() const; // last chunk; + int one_chunk() const; // true if hd == tl() + +public: + +// constructors, etc. + + Plex(); // no-op + + virtual ~Plex(); + + +// Access functions + + virtual & operator [] (int idx) = 0; // access by index; + virtual & operator () (Pix p) = 0; // access by Pix; + + virtual & high_element () = 0; // access high element + virtual & low_element () = 0; // access low element + +// read-only versions for const Plexes + + virtual const & operator [] (int idx) const = 0; // access by index; + virtual const & operator () (Pix p) const = 0; // access by Pix; + + virtual const & high_element () const = 0; // access high element + virtual const & low_element () const = 0; // access low element + + +// Index functions + + virtual int valid (int idx) const = 0; // idx is an OK index + + virtual int low() const = 0; // lowest index or fence if none + virtual int high() const = 0; // highest index or low-1 if none + + int ecnef() const; // low limit index (low-1) + int fence() const; // high limit index (high+1) + + virtual void prev(int& idx) const= 0; // set idx to preceding index + // caution: pred may be out of bounds + + virtual void next(int& idx) const = 0; // set to next index + // caution: succ may be out of bounds + + virtual Pix first() const = 0; // Pix to low element or 0 + virtual Pix last() const = 0; // Pix to high element or 0 + virtual void prev(Pix& pix) const = 0; // preceding pix or 0 + virtual void next(Pix& pix) const = 0; // next pix or 0 + virtual int owns(Pix p) const = 0; // p is an OK Pix + +// index<->Pix + + virtual int Pix_to_index(Pix p) const = 0; // get index via Pix + virtual Pix index_to_Pix(int idx) const = 0; // Pix via index + +// Growth + + virtual int add_high(const elem) =0;// add new element at high end + // return new high + + virtual int add_low(const elem) = 0; // add new low element, + // return new low + +// Shrinkage + + virtual int del_high() = 0; // remove the element at high end + // return new high + virtual int del_low() = 0; // delete low element, return new lo + + // caution: del_low/high + // does not necessarily + // immediately call ::~ + + +// operations on multiple elements + + virtual void fill(const x); // set all elements = x + virtual void fill(const x, int from, int to); // fill from to to + virtual void clear() = 0; // reset to zero-sized Plex + virtual int reset_low(int newlow); // change low index,return old + virtual void reverse(); // reverse in-place + virtual void append(const Plex& a); // concatenate a copy + virtual void prepend(const Plex& a); // prepend a copy + +// status + + virtual int can_add_high() const = 0; + virtual int can_add_low() const = 0; + + int length () const; // number of slots + + int empty () const; // is the plex empty? + virtual int full() const = 0; // it it full? + + int chunk_size() const; // report chunk size; + + virtual int OK() const = 0; // representation invariant + + void error(const char* msg) const; + void index_error() const; + void empty_error() const; + void full_error() const; +}; + + +// IChunk ops + +inline int IChunk:: size() const +{ + return top - base; +} + + +inline int IChunk:: base_index() const +{ + return base; +} + +inline int IChunk:: low_index() const +{ + return low; +} + +inline int IChunk:: fence_index() const +{ + return fence; +} + +inline int IChunk:: top_index() const +{ + return top; +} + +inline * IChunk:: pointer_to(int i) const +{ + return &(data[i-base]); +} + +inline int IChunk:: index_of(const * p) const +{ + return ((int)p - (int)data) / sizeof() + base; +} + +inline int IChunk:: possible_index(int i) const +{ + return i >= base && i < top; +} + +inline int IChunk:: possible_pointer(const * p) const +{ + return p >= data && p < &(data[top-base]); +} + +inline int IChunk:: actual_index(int i) const +{ + return i >= low && i < fence; +} + +inline int IChunk:: actual_pointer(const * p) const +{ + return p >= data && p < &(data[fence-base]); +} + +inline int IChunk:: can_grow_high () const +{ + return fence < top; +} + +inline int IChunk:: can_grow_low () const +{ + return base < low; +} + +inline * IChunk:: invalidate() +{ + * p = data; + data = 0; + return p; +} + + +inline IChunk* IChunk::prev() const +{ + return prv; +} + +inline IChunk* IChunk::next() const +{ + return nxt; +} + +inline void IChunk::link_to_prev(IChunk* prev) +{ + nxt = prev->nxt; + prv = prev; + nxt->prv = this; + prv->nxt = this; +} + +inline void IChunk::link_to_next(IChunk* next) +{ + prv = next->prv; + nxt = next; + nxt->prv = this; + prv->nxt = this; +} + +inline void IChunk::unlink() +{ + IChunk* n = nxt; + IChunk* p = prv; + n->prv = p; + p->nxt = n; + prv = nxt = this; +} + +inline int IChunk:: empty() const +{ + return low == fence; +} + +inline int IChunk:: full() const +{ + return top - base == fence - low; +} + +inline int IChunk:: first_index() const +{ + return (low == fence)? fence : low; +} + +inline int IChunk:: last_index() const +{ + return (low == fence)? low - 1 : fence - 1; +} + +inline int IChunk:: succ(int i) const +{ + return (i < low) ? low : i + 1; +} + +inline int IChunk:: pred(int i) const +{ + return (i > fence) ? (fence - 1) : i - 1; +} + +inline int IChunk:: valid_index(int i) const +{ + return i >= low && i < fence; +} + +inline int IChunk:: valid_pointer(const * p) const +{ + return p >= &(data[low - base]) && p < &(data[fence - base]); +} + +inline * IChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + return &(data[fence++ - base]); +} + +inline * IChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + return &(data[--low - base]); +} + +inline void IChunk:: shrink_high () +{ + if (empty()) empty_error(); + --fence; +} + +inline void IChunk:: shrink_low () +{ + if (empty()) empty_error(); + ++low; +} + +inline * IChunk::first_pointer() const +{ + return (low == fence)? 0 : &(data[low - base]); +} + +inline * IChunk::last_pointer() const +{ + return (low == fence)? 0 : &(data[fence - base - 1]); +} + +inline * IChunk::succ(* p) const +{ + return ((p+1) < &(data[low - base]) || (p+1) >= &(data[fence - base])) ? + 0 : (p+1); +} + +inline * IChunk::pred(* p) const +{ + return ((p-1) < &(data[low - base]) || (p-1) >= &(data[fence - base])) ? + 0 : (p-1); +} + + +// generic Plex operations + +inline Plex::Plex() {} + +inline int Plex::chunk_size() const +{ + return csize; +} + +inline int Plex::ecnef () const +{ + return lo - 1; +} + + +inline int Plex::fence () const +{ + return fnc; +} + +inline int Plex::length () const +{ + return fnc - lo; +} + +inline int Plex::empty () const +{ + return fnc == lo; +} + +inline IChunk* Plex::tl() const +{ + return hd->prev(); +} + +inline int Plex::one_chunk() const +{ + return hd == hd->prev(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Queue.ccP b/gnu/lib/libg++/g++-include/Queue.ccP new file mode 100644 index 0000000000..fb48d952ff --- /dev/null +++ b/gnu/lib/libg++/g++-include/Queue.ccP @@ -0,0 +1,14 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Queue.h" + +Queue::~Queue() {} + + +// error handling + +void Queue::error(const char* msg) +{ + (*lib_error_handler)("Queue", msg); +} diff --git a/gnu/lib/libg++/g++-include/Queue.hP b/gnu/lib/libg++/g++-include/Queue.hP new file mode 100644 index 0000000000..73db6e034e --- /dev/null +++ b/gnu/lib/libg++/g++-include/Queue.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Queue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Queue_h + +#include + +#include ".defs.h" + +class Queue +{ +public: + Queue() { } + virtual ~Queue(); + + virtual void enq( item) = 0; + virtual deq() = 0; + virtual & front() = 0; + virtual void del_front() = 0; + + virtual void clear() = 0; + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + void error(const char*); + + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/RAVLMap.ccP b/gnu/lib/libg++/g++-include/RAVLMap.ccP new file mode 100644 index 0000000000..7537dd0788 --- /dev/null +++ b/gnu/lib/libg++/g++-include/RAVLMap.ccP @@ -0,0 +1,690 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..RAVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(RAVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(RAVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(RAVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(RAVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(RAVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(RAVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +RAVLNode* RAVLMap::leftmost() +{ + RAVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +RAVLNode* RAVLMap::rightmost() +{ + RAVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +RAVLNode* RAVLMap::succ(RAVLNode* t) +{ + RAVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +RAVLNode* RAVLMap::pred(RAVLNode* t) +{ + RAVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix RAVLMap::seek( key) +{ + RAVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +int RAVLMap::rankof( key) +{ + int r; + RAVLNode* t = root; + if (t == 0) + return 0; + for (r=t->rank; t != 0; r+=t->rank) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return r; + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + { + r -= t->rank; + t = t->lt; + } + } + else if (rthread(t)) + return 0; + else + { + t = t->rt; + } + } + return 0; +} + +Pix RAVLMap::ranktoPix(int i) +{ + int r; + RAVLNode* t = root; + + if ((i<1)||(i>count)) + return 0; + for (r=t->rank; r!=i; r+=t->rank) + { + if (r>i) + { + r -= t->rank; + t = t->lt; + } + else + t = t->rt; + } + return Pix(t); +} + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static RAVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases +static int _rank_changed; // for rank computation + + +void RAVLMap:: _add(RAVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new RAVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->lt); + if (_rank_changed) ++t->rank; + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new RAVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +& RAVLMap::operator [] ( item) +{ + if (root == 0) + { + ++count; + root = new RAVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _rank_changed = 0; + _add(root); + return _found_node->cont; + } +} + + +void RAVLMap::_del(RAVLNode* par, RAVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + RAVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + RAVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else // replace item & find someone deletable + { + RAVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (_rank_changed) --t->rank; + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + +void RAVLMap::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _rank_changed = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void RAVLMap::_kill(RAVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +RAVLMap::RAVLMap(RAVLMap& b) :Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int RAVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + RAVLNode* trail = leftmost(); + v &= rankof(trail->item) == n; + RAVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + v &= rankof(t->item) == n; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/RAVLMap.hP b/gnu/lib/libg++/g++-include/RAVLMap.hP new file mode 100644 index 0000000000..d3c523ee29 --- /dev/null +++ b/gnu/lib/libg++/g++-include/RAVLMap.hP @@ -0,0 +1,147 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + ranking code from Paul Anderson (paul%lfcs.ed.ac.uk) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _RAVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _RAVLMap_h 1 + +#include "..Map.h" + +struct RAVLNode +{ + RAVLNode* lt; + RAVLNode* rt; + item; + cont; + int rank; + char stat; + RAVLNode( h, c, + RAVLNode* l=0, RAVLNode* r=0, int k=1); + ~RAVLNode(); +}; + +inline RAVLNode::RAVLNode( h, c, + RAVLNode* l, RAVLNode* r, int k) + :item(h), cont(c), lt(l), rt(r), rank(k), stat(0) {} + +inline RAVLNode::~RAVLNode() {} + +typedef RAVLNode* RAVLNodePtr; + + +class RAVLMap : public Map +{ +protected: + RAVLNode* root; + + RAVLNode* leftmost(); + RAVLNode* rightmost(); + RAVLNode* pred(RAVLNode* t); + RAVLNode* succ(RAVLNode* t); + void _kill(RAVLNode* t); + void _add(RAVLNode*& t); + void _del(RAVLNode* p, RAVLNode*& t); + +public: + RAVLMap( dflt); + RAVLMap(RAVLMap& a); + ~RAVLMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + Pix ranktoPix(int i); + int rankof( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline RAVLMap::~RAVLMap() +{ + _kill(root); +} + +inline RAVLMap::RAVLMap( dflt) :Map(dflt) +{ + root = 0; +} + + +inline Pix RAVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix RAVLMap::last() +{ + return Pix(rightmost()); +} + +inline void RAVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((RAVLNode*)i)); +} + +inline void RAVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((RAVLNode*)i)); +} + +inline & RAVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((RAVLNode*)i)->item; +} + +inline & RAVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((RAVLNode*)i)->cont; +} + +inline void RAVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int RAVLMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/RPlex.ccP b/gnu/lib/libg++/g++-include/RPlex.ccP new file mode 100644 index 0000000000..0dbd2cee7e --- /dev/null +++ b/gnu/lib/libg++/g++-include/RPlex.ccP @@ -0,0 +1,477 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".RPlex.h" + +typedef IChunk* _IChunk_ptr; + +RPlex:: RPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +RPlex:: RPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize+lo)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + + +RPlex:: RPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +void RPlex::make_initial_chunks(int up) +{ + int count = 0; + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + set_cache((IChunk*)hd); + + maxch = MIN_NCHUNKS; + if (maxch < count * 2) + maxch = count * 2; + chunks = new _IChunk_ptr[maxch]; + lch = maxch / 3; + fch = lch + count; + base = ch->base_index() - csize * lch; + int k = lch; + do + { + chunks[k++] = ch; + set_cache(ch->next()); + } while (ch != hd); +} + +RPlex:: RPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + fill(initval); +} + +RPlex::RPlex(const RPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void RPlex::operator= (const RPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void RPlex::cache(const * p) const +{ + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) index_error(); + } + set_cache(t); +} + +int RPlex::owns(Pix px) const +{ + * p = (*)px; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + set_cache(t); + return 1; +} + + +* RPlex::dosucc(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + int i = t->index_of(p) + 1; + if (i >= fnc) return 0; + if (i >= t->fence_index()) t = (t->next()); + set_cache(t); + return t->pointer_to(i); +} + +* RPlex::dopred(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->prev()); + if (t == old) return 0; + } + int i = t->index_of(p) - 1; + if (i < lo) return 0; + if (i < t->low_index()) t = (t->prev()); + set_cache(t); + return (t->pointer_to(i)); +} + +int RPlex::add_high(const elem) +{ + IChunk* t = tl(); + if (!t->can_grow_high()) + { + if (t->IChunk::empty() && one_chunk()) + { + t->clear(fnc); + base = t->base_index() - lch * csize; + } + else + { + * data = new [csize]; + t = (new IChunk(data, fnc, fnc, fnc,fnc+csize)); + t->link_to_prev(tl()); + if (fch == maxch) + { + maxch *= 2; + IChunk** newch = new _IChunk_ptr [maxch]; + memcpy(newch, chunks, fch * sizeof(_IChunk_ptr)); + delete chunks; + chunks = newch; + } + chunks[fch++] = t; + } + } + *((t->IChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int RPlex::del_high () +{ + if (empty()) empty_error(); + IChunk* t = tl(); + if (t->IChunk::empty()) // kill straggler first + { + IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + t->IChunk::shrink_high(); + if (t->IChunk::empty() && !one_chunk()) + { + IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + set_cache(t); + return --fnc - 1; +} + +int RPlex::add_low (const elem) +{ + IChunk* t = hd; + if (!t->can_grow_low()) + { + if (t->IChunk::empty() && one_chunk()) + { + t->cleardown(lo); + base = t->base_index() - lch * csize; + } + else + { + * data = new [csize]; + hd = new IChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ( hd); + if (lch == 0) + { + lch = maxch; + fch += maxch; + maxch *= 2; + IChunk** newch = new _IChunk_ptr [maxch]; + memcpy(&(newch[lch]), chunks, lch * sizeof(_IChunk_ptr)); + delete chunks; + chunks = newch; + base = t->base_index() - (lch - 1) * csize; + } + chunks[--lch] = t; + } + } + *((t->IChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + + +int RPlex::del_low () +{ + if (empty()) empty_error(); + IChunk* t = hd; + if (t->IChunk::empty()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + t->IChunk::shrink_low(); + if (t->IChunk::empty() && !one_chunk()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + set_cache(t); + return ++lo; +} + +void RPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + IChunk* loch = hd; + IChunk* hich = tl(); + while (l < h) + { + * lptr = loch->pointer_to(l); + * hptr = hich->pointer_to(h); + tmp = *lptr; + *lptr = *hptr; + *hptr = tmp; + if (++l >= loch->fence_index()) loch = loch->next(); + if (--h < hich->low_index()) hich = hich->prev(); + } +} + +void RPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void RPlex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void RPlex::clear() +{ + for (int i = lch + 1; i < fch; ++i) + del_chunk(chunks[i]); + fch = lch + 1; + set_cache(chunks[lch]); + ch->IChunk::clear(lo); + fnc = lo; +} + +int RPlex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + base = hd->base_index() - lch * csize; + return old; +} + + +int RPlex::OK () const +{ + int v = hd != 0 && ch != 0; // at least one chunk + + v &= fnc == tl()->fence_index(); // last chunk fnc == plex fnc + v &= lo == hd->IChunk::low_index(); // first lo == plex lo + + v &= base == hd->base_index() - lch * csize; // base is correct; + v &= lch < fch; + v &= fch <= maxch; // within allocation; + +// loop for others: + + int k = lch; // to cross-check nch + + int found_ch = 0; // to make sure ch is in list; + const IChunk* t = (hd); + for (;;) + { + v &= chunks[k++] == t; // each chunk is at proper index + if (t == ch) ++found_ch; + v &= t->IChunk::OK(); // each chunk is OK + if (t == tl()) + break; + else // and has indices contiguous to succ + { + v &= t->top_index() == t->next()->base_index(); + if (t != hd) // internal chunks full + { + v &= !t->empty(); + v &= !t->can_grow_low(); + v &= !t->can_grow_high(); + } + t = t->next(); + } + } + v &= found_ch == 1; + v &= fch == k; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/RPlex.hP b/gnu/lib/libg++/g++-include/RPlex.hP new file mode 100644 index 0000000000..ed28c357e4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/RPlex.hP @@ -0,0 +1,257 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _RPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _RPlex_h 1 + +#include ".Plex.h" + +// minimum number of chunks to index + +#ifndef MIN_NCHUNKS +#define MIN_NCHUNKS 16 +#endif + +class RPlex: public Plex +{ + int base; // base index of lowest chunk + int lch; // index of lowest used chunk + int fch; // 1 + index of highest used chunk + int maxch; // max chunks in array + IChunk** chunks; // array of chunks + IChunk* ch; // cached chunk + + void make_initial_chunks(int up = 1); + + void cache(int idx) const; + void cache(const * p) const; + * dopred(const * p) const; + * dosucc(const * p) const; + + void set_cache(const IChunk* t) const; // logically, + // not physically const + +public: + RPlex(); // set low = 0; + // fence = 0; + // csize = default + + RPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + RPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + RPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + RPlex(const RPlex&); + + ~RPlex(); + + void operator= (const RPlex&); + +// virtuals + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int reset_low(int newlow); + + int OK () const; +}; + + +inline void RPlex::prev(int& idx) const +{ + --idx; +} + +inline void RPlex::next(int& idx) const +{ + ++idx; +} + +inline int RPlex::full () const +{ + return 0; +} + +inline int RPlex::can_add_high() const +{ + return 1; +} + +inline int RPlex::can_add_low() const +{ + return 1; +} + +inline int RPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int RPlex::low() const +{ + return lo; +} + +inline int RPlex::high() const +{ + return fnc - 1; +} + +inline void RPlex::set_cache(const IChunk* t) const +{ + ((RPlex*)(this))->ch = (IChunk*)t; +} + +inline void RPlex::cache(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + set_cache(chunks[(idx - base) / csize]); +} + +inline & RPlex::low_element () +{ + cache(lo); return *(ch->pointer_to(lo)); +} + +inline & RPlex::high_element () +{ + cache(fnc-1); return *(ch->pointer_to(fnc - 1)); +} + +inline const & RPlex::low_element () const +{ + cache(lo); return *((const *)(ch->pointer_to(lo))); +} + +inline const & RPlex::high_element () const +{ + cache(fnc-1); return *((const *)(ch->pointer_to(fnc - 1))); +} + +inline int RPlex::Pix_to_index(Pix px) const +{ + * p = (*)px; + if (!ch->actual_pointer(p)) cache(p); + return ch->index_of(p); +} + +inline Pix RPlex::index_to_Pix(int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return (Pix)(ch->pointer_to(idx)); +} + +inline Pix RPlex::first() const +{ + return Pix(hd->IChunk::first_pointer()); +} + +inline Pix RPlex::last() const +{ + return Pix(tl()->IChunk::last_pointer()); +} + +inline void RPlex::prev(Pix& p) const +{ + Pix q = Pix(ch->IChunk::pred((*)p)); + p = (q == 0)? Pix(dopred((*)p)) : q; +} + +inline void RPlex::next(Pix& p) const +{ + Pix q = Pix(ch->IChunk::succ((*)p)); + p = (q == 0)? Pix(dosucc((*)p)) : q; +} + +inline & RPlex:: operator () (Pix p) +{ + return *((*)p); +} + + +inline & RPlex:: operator [] (int idx) +{ + cache(idx); return *(ch->pointer_to(idx)); +} + +inline const & RPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline const & RPlex:: operator [] (int idx) const +{ + cache(idx); return *((const *)(ch->pointer_to(idx))); +} + +inline RPlex::~RPlex() +{ + delete chunks; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SLBag.ccP b/gnu/lib/libg++/g++-include/SLBag.ccP new file mode 100644 index 0000000000..50d2447c7d --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLBag.ccP @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLBag.h" + +int SLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix SLBag::seek( item, Pix i) +{ + if (i == 0) i = first(); else next(i); + for (; i != 0 && (!(EQ(p(i), item))); p.next(i)); + return i; +} + +int SLBag::nof( item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (EQ((*this)(p), item)) ++n; + return n; +} + + +void SLBag::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + +void SLBag::remove( item) +{ + Pix i = p.first(); + while (i != 0 && EQ(p(i), item)) + { + --count; + p.del_front(); + i = p.first(); + } + if (i != 0) + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + i = trail; + p.next(i); + } + else + { + trail = i; + p.next(i); + } + } + } +} + diff --git a/gnu/lib/libg++/g++-include/SLBag.hP b/gnu/lib/libg++/g++-include/SLBag.hP new file mode 100644 index 0000000000..edb648e9d3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLBag.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLBag_h 1 + +#include ".Bag.h" +#include ".SLList.h" + +class SLBag : public Bag +{ +protected: + SLList p; + +public: + SLBag(); + SLBag(const SLBag&); + + Pix add( item); + void del( item); + void remove(item); + int contains( item); + int nof( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline SLBag::SLBag() : p() { count = 0; } + +inline SLBag::SLBag(const SLBag& s) : p(s.p) { count = s.count; } + +inline Pix SLBag::first() +{ + return p.first(); +} + +inline void SLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & SLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void SLBag::clear() +{ + count = 0; p.clear(); +} + +inline int SLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline Pix SLBag::add( item) +{ + ++count; + return p.append(item); +} + +inline int SLBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SLList.ccP b/gnu/lib/libg++/g++-include/SLList.ccP new file mode 100644 index 0000000000..3ebd8d5bc9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLList.ccP @@ -0,0 +1,292 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include +#include ".SLList.h" + +void SLList::error(const char* msg) +{ + (*lib_error_handler)("SLList", msg); +} + +int SLList::length() +{ + int l = 0; + SLListNode* t = last; + if (t != 0) do { ++l; t = t->tl; } while (t != last); + return l; +} + +SLList::SLList(const SLList& a) +{ + if (a.last == 0) + last = 0; + else + { + SLListNode* p = a.last->tl; + SLListNode* h = new SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + return; + } + p = p->tl; + SLListNode* n = new SLListNode(p->hd); + last->tl = n; + last = n; + } + } +} + +SLList& SLList::operator = (const SLList& a) +{ + if (last != a.last) + { + clear(); + if (a.last != 0) + { + SLListNode* p = a.last->tl; + SLListNode* h = new SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + break; + } + p = p->tl; + SLListNode* n = new SLListNode(p->hd); + last->tl = n; + last = n; + } + } + } + return *this; +} + +void SLList::clear() +{ + if (last == 0) + return; + + SLListNode* p = last->tl; + last->tl = 0; + last = 0; + + while (p != 0) + { + SLListNode* nxt = p->tl; + delete(p); + p = nxt; + } +} + + +Pix SLList::prepend( item) +{ + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix SLList::prepend(SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix SLList::append( item) +{ + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +Pix SLList::append(SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +void SLList::join(SLList& b) +{ + SLListNode* t = b.last; + b.last = 0; + if (last == 0) + last = t; + else if (t != 0) + { + SLListNode* f = last->tl; + last->tl = t->tl; + t->tl = f; + last = t; + } +} + +Pix SLList::ins_after(Pix p, item) +{ + SLListNode* u = (SLListNode*)p; + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else if (u == 0) // ins_after 0 means prepend + { + t->tl = last->tl; + last->tl = t; + } + else + { + t->tl = u->tl; + u->tl = t; + if (u == last) + last = t; + } + return Pix(t); +} + + +void SLList::del_after(Pix p) +{ + SLListNode* u = (SLListNode*)p; + if (last == 0 || u == last) error("cannot del_after last"); + if (u == 0) u = last; // del_after 0 means delete first + SLListNode* t = u->tl; + if (u == t) + last = 0; + else + { + u->tl = t->tl; + if (last == t) + last = u; + } + delete t; +} + +int SLList::owns(Pix p) +{ + SLListNode* t = last; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->tl; + } while (t != last); + } + return 0; +} + + SLList::remove_front() +{ + if (last == 0) error("remove_front of empty list"); + SLListNode* t = last->tl; + res = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return res; +} + +int SLList::remove_front(& x) +{ + if (last == 0) + return 0; + else + { + SLListNode* t = last->tl; + x = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return 1; + } +} + + +void SLList::del_front() +{ + if (last == 0) error("del_front of empty list"); + SLListNode* t = last->tl; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; +} + +int SLList::OK() +{ + int v = 1; + if (last != 0) + { + SLListNode* t = last; + long count = MAXLONG; // Lots of chances to find last! + do + { + count--; + t = t->tl; + } while (count > 0 && t != last); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/SLList.hP b/gnu/lib/libg++/g++-include/SLList.hP new file mode 100644 index 0000000000..e5570bdf8f --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLList.hP @@ -0,0 +1,137 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLList_h 1 + +#include +#include ".defs.h" + +#ifndef _SLListNode_h +#define _SLListNode_h 1 + +struct SLListNode +{ + SLListNode* tl; + hd; + SLListNode() { } + SLListNode(const h, SLListNode* t = 0); + ~SLListNode() { } +}; + + +inline SLListNode::SLListNode(const h, SLListNode* t) +:hd(h), tl(t) {} + +typedef SLListNode* SLListNodePtr; + +#endif + + +class SLList +{ +protected: + SLListNode* last; + +public: + SLList(); + SLList(const SLList& a); + ~SLList(); + + SLList& operator = (const SLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend( item); + Pix append( item); + + void join(SLList&); + + Pix prepend(SLListNode*); + Pix append(SLListNode*); + + & operator () (Pix p); + Pix first(); + void next(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, item); + void del_after(Pix p); + + & front(); + & rear(); + remove_front(); + int remove_front(& x); + void del_front(); + + void error(const char* msg); + int OK(); +}; + +inline SLList::~SLList() +{ + clear(); +} + +inline SLList::SLList() +{ + last = 0; +} + +inline int SLList::empty() +{ + return last == 0; +} + + +inline Pix SLList::first() +{ + return (last == 0)? 0 : Pix(last->tl); +} + +inline void SLList::next(Pix& p) +{ + p = (p == 0 || p == last)? 0 : Pix(((SLListNode*)(p))->tl); +} + +inline & SLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((SLListNode*)(p))->hd; +} + +inline & SLList::front() +{ + if (last == 0) error("front: empty list"); + return last->tl->hd; +} + +inline & SLList::rear() +{ + if (last == 0) error("rear: empty list"); + return last->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SLQueue.ccP b/gnu/lib/libg++/g++-include/SLQueue.ccP new file mode 100644 index 0000000000..8a5935b775 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLQueue.h" diff --git a/gnu/lib/libg++/g++-include/SLQueue.hP b/gnu/lib/libg++/g++-include/SLQueue.hP new file mode 100644 index 0000000000..20fd74c9c5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLQueue.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _SLQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLQueue_h + +#include ".SLList.h" +#include ".Queue.h" + +class SLQueue : public Queue +{ + SLList p; + +public: + SLQueue(); + SLQueue(const SLQueue& q); + ~SLQueue(); + + void operator = (const SLQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline SLQueue::SLQueue() :p() {} +inline SLQueue::SLQueue(const SLQueue& q) : p(q.p) {} + +inline SLQueue::~SLQueue() {} + +inline void SLQueue::enq(item) +{ + p.append(item); +} + +inline SLQueue::deq() +{ + return p.remove_front(); +} + +inline & SLQueue::front() +{ + return p.front(); +} + + +inline void SLQueue::del_front() +{ + p.del_front(); +} + +inline void SLQueue::operator =(const SLQueue& s) +{ + p = s.p; +} + +inline int SLQueue::empty() +{ + return p.empty(); +} + +inline int SLQueue::full() +{ + return 0; +} + +inline int SLQueue::length() +{ + return p.length(); +} + +inline int SLQueue::OK() +{ + return p.OK(); +} + +inline void SLQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SLSet.ccP b/gnu/lib/libg++/g++-include/SLSet.ccP new file mode 100644 index 0000000000..5f580849ff --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLSet.ccP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLSet.h" + +int SLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix SLSet::seek( item) +{ + for (Pix i = p.first(); i != 0 && !EQ(p(i),item); p.next(i)); + return i; +} + +Pix SLSet::add( item) +{ + Pix i = seek(item); + if (i == 0) + { + ++count; + i = p.append(item); + } + return i; +} + +void SLSet::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + diff --git a/gnu/lib/libg++/g++-include/SLSet.hP b/gnu/lib/libg++/g++-include/SLSet.hP new file mode 100644 index 0000000000..fcf153633f --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLSet.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLSet_h 1 + +#include ".Set.h" +#include ".SLList.h" + +class SLSet : public Set +{ +protected: + SLList p; + +public: + SLSet(); + SLSet(const SLSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); +}; + +inline SLSet::SLSet() : p() { count = 0; } + +inline SLSet::SLSet(const SLSet& s) : p(s.p) { count = s.count; } + +inline Pix SLSet::first() +{ + return p.first(); +} + +inline void SLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & SLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void SLSet::clear() +{ + count = 0; p.clear(); +} + +inline int SLSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int SLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SLStack.ccP b/gnu/lib/libg++/g++-include/SLStack.ccP new file mode 100644 index 0000000000..3996b41fac --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLStack.h" diff --git a/gnu/lib/libg++/g++-include/SLStack.hP b/gnu/lib/libg++/g++-include/SLStack.hP new file mode 100644 index 0000000000..e20d9b9c2a --- /dev/null +++ b/gnu/lib/libg++/g++-include/SLStack.hP @@ -0,0 +1,109 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLStack_h 1 + +#include ".SLList.h" +#include ".Stack.h" + +class SLStack : public Stack +{ + SLList p; + +public: + SLStack(); + SLStack(const SLStack& s); + ~SLStack(); + + void operator = (const SLStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + +inline SLStack::SLStack() :p() {} +inline SLStack::SLStack(const SLStack& a) : p(a.p) {} +inline SLStack::~SLStack() {} + +inline void SLStack::push( item) +{ + p.prepend(item); +} + +inline SLStack::pop() +{ + return p.remove_front(); +} + +inline & SLStack::top() +{ + return p.front(); +} + +inline void SLStack::del_top() +{ + p.del_front(); +} + +inline void SLStack::operator =(const SLStack& s) +{ + p = s.p; +} + +inline int SLStack::empty() +{ + return p.empty(); +} + +inline int SLStack::full() +{ + return 0; +} + +inline int SLStack::length() +{ + return p.length(); +} + +inline int SLStack::OK() +{ + return p.OK(); +} + +inline void SLStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Set.ccP b/gnu/lib/libg++/g++-include/Set.ccP new file mode 100644 index 0000000000..f312aa15cc --- /dev/null +++ b/gnu/lib/libg++/g++-include/Set.ccP @@ -0,0 +1,116 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".Set.h" + + +Pix Set::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ((*this)(i), item)); next(i)); + return i; +} + +int Set::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void Set::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + +int Set::contains ( item) +{ + return seek(item) != 0; +} + +int Set::operator <= (Set& b) +{ + if (count > b.count) return 0; + if (count == 0) return 1; + for (Pix i = first(); i; next(i)) if (b.seek((*this)(i)) == 0) return 0; + return 1; +} + +int Set::operator == (Set& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + Pix i = first(); + Pix j = b.first(); + while (n-- > 0) + { + if ((b.seek((*this)(i)) == 0) || (seek(b(j)) == 0)) return 0; + next(i); + b.next(j); + } + return 1; +} + +int Set::operator != (Set& b) +{ + return !(*this == b); +} + +void Set::operator |= (Set& b) +{ + if (&b != this) + for (Pix i = b.first(); i; b.next(i)) add(b(i)); +} + +void Set::operator -= (Set& b) +{ + if (&b == this) + clear(); + else + for (Pix i = b.first(); i; b.next(i)) del(b(i)); +} + + +void Set::operator &= (Set& b) +{ + if (&b != this) + { + Pix i = first(); + Pix n = i; + while (i != 0) + { + next(n); + if (b.seek((*this)(i)) == 0) del((*this)(i)); + i = n; + } + } +} + +void Set::error(const char* msg) +{ + (*lib_error_handler)("Set", msg); +} diff --git a/gnu/lib/libg++/g++-include/Set.hP b/gnu/lib/libg++/g++-include/Set.hP new file mode 100644 index 0000000000..6c21922627 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Set.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Set_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Set_h 1 + +#include +#include ".defs.h" + +class Set +{ +protected: + + int count; + +public: + virtual ~Set(); + + int length(); // current number of items + int empty(); + + virtual Pix add( item) = 0; // add item; return Pix + virtual void del( item) = 0; // delete item + virtual int contains( item); // is item in set? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & operator () (Pix i) = 0; // access item at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( item); // Pix of item + + void operator |= (Set& b); // add all items in b + void operator -= (Set& b); // delete items also in b + void operator &= (Set& b); // delete items not in b + + int operator == (Set& b); + int operator != (Set& b); + int operator <= (Set& b); + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline Set::~Set() {} + +inline int Set::length() +{ + return count; +} + +inline int Set::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SkipBag.ccP b/gnu/lib/libg++/g++-include/SkipBag.ccP new file mode 100644 index 0000000000..cc347e9813 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipBag.ccP @@ -0,0 +1,322 @@ +// This may look like C code, but it is really -*- C++ -*- + +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include +#include +#include ".SkipBag.h" + +MLCG* SkipBag::gen = 0; +int SkipBaginit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +SkipBag::SkipBag(long size) +: level(0), + header(new SkipBagNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipBagNodePtr) header; +} + +SkipBag::SkipBag(SkipBag& b) +: level (0), + header (new SkipBagNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipBagNodePtr)header; + + for (SkipBagNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +Pix SkipBag::add ( item) +{ + SkipBagNodePtr *update = new SkipBagNodePtr[max_levels+1]; + SkipBagNodePtr curr = (SkipBagNodePtr) this->header; + int l = level; + SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipBagNodePtr)header; + }; + + temp = new RealSkipBagNode (item, l); + SkipBagNodePtr *temp_forward = temp->forward; + + do + { + SkipBagNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void SkipBag::del( key) +{ + + int l = level; + int curr_level = level; + SkipBagNodePtr *update = new SkipBagNodePtr[max_levels+1]; + SkipBagNodePtr curr = (SkipBagNodePtr)header; + SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipBagNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipBagNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipBagNodePtr SkipBag::rightmost() +{ + SkipBagNodePtr temp; + SkipBagNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipBagNodePtr SkipBag::pred(SkipBagNodePtr t) +{ + SkipBagNodePtr temp, curr = (SkipBagNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipBag::_kill() +{ + SkipBagNode *p = this->header->forward[0]; + + while (p != header) + { + SkipBagNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipBag::clear() +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipBagNodePtr)header; +} + +Pix SkipBag::seek( key, Pix i) +{ + SkipBagNodePtr temp; + SkipBagNode *curr = header; + int l = level; + if (i) + curr = (SkipBagNode *)i; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +int SkipBag::nof( item) +{ + int n = 0; + SkipBagNodePtr t = (SkipBagNodePtr)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && EQ(item, t->item)); + } + return n; +} + +void SkipBag::remove( key) +{ + Pix t = seek(key); + while (t != 0) + { + del(key); + t = seek(key); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipBag::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipBag::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipBagNodePtr trail = leftmost(); + SkipBagNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipBaginit::SkipBaginit() +{ + if (!count) + SkipBag::gen = new MLCG(time(0)); + count++; +} + +SkipBaginit::~SkipBaginit() +{ + count--; + if (!count) + delete SkipBag::gen; +} diff --git a/gnu/lib/libg++/g++-include/SkipBag.hP b/gnu/lib/libg++/g++-include/SkipBag.hP new file mode 100644 index 0000000000..1bfe9da446 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipBag.hP @@ -0,0 +1,171 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipBag_h 1 + +#include ".Bag.h" + +#include +#include + +class SkipBag; +class RealSkipBagNode; + +class SkipBagNode +{ +friend class SkipBag; + private: + RealSkipBagNode * * forward; + SkipBagNode(int size); +}; + +class RealSkipBagNode : public SkipBagNode +{ +friend class SkipBag; + private: + item; + RealSkipBagNode( h, int size); +}; + +typedef RealSkipBagNode* SkipBagNodePtr; + +inline SkipBagNode::SkipBagNode(int size) +: forward(new SkipBagNodePtr[size+1]) +{ +} + +inline RealSkipBagNode::RealSkipBagNode( h, int size) +: item(h), + SkipBagNode(size) +{ +} + +class SkipBag : public Bag +{ +friend class SkipBaginit; + protected: + SkipBagNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipBagNodePtr leftmost(void); + SkipBagNodePtr rightmost(void); + SkipBagNodePtr pred(SkipBagNodePtr t); + SkipBagNodePtr succ(SkipBagNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + SkipBag(long size=DEFAULT_INITIAL_CAPACITY); + SkipBag(SkipBag& a); + ~SkipBag(void); + + Pix add( i); + void del( i); + void remove(i); + int nof( i); + int contains( i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + & operator () (Pix i); + Pix seek( i, Pix from = 0); + + Pix last(void); + void prev(Pix& i); + + int OK(void); +}; + +inline SkipBagNodePtr SkipBag::leftmost(void) +{ + return header->forward[0]; +} + +inline SkipBagNodePtr SkipBag::succ(SkipBagNodePtr t) +{ + SkipBagNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix SkipBag::first(void) +{ + return Pix(leftmost()); +} + +inline Pix SkipBag::last(void) +{ + return Pix(rightmost()); +} + +inline void SkipBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipBagNodePtr)i)); +} + +inline & SkipBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipBagNodePtr)i)->item; +} + +inline void SkipBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipBagNodePtr)i)); +} + +inline int SkipBag::contains( key) +{ + return seek(key) != 0; +} + +inline SkipBag::~SkipBag() +{ + _kill(); + delete header; +} + +static class SkipBaginit +{ + public: + SkipBaginit(); + ~SkipBaginit(); + private: + static int count; +} skipBaginit; + +#endif diff --git a/gnu/lib/libg++/g++-include/SkipMap.ccP b/gnu/lib/libg++/g++-include/SkipMap.ccP new file mode 100644 index 0000000000..8b6afe2edd --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipMap.ccP @@ -0,0 +1,307 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include +#include "..SkipMap.h" + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +MLCG* SkipMap::gen = 0; +int SkipMapinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1) n++; + return n; +} + +SkipMap::SkipMap( dflt, long size) +: Map(dflt), + level(0), + header(new SkipMapNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipMapNodePtr) header; +} + +SkipMap::SkipMap(SkipMap& b) +: Map(b.def), + level (0), + header (new SkipMapNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipMapNodePtr)header; + + for (SkipMapNodePtr t = b.leftmost(); t; t = b.succ(t)) + (*this)[t->item] = t->cont; +} + +& SkipMap::operator [] ( item) +{ + SkipMapNodePtr *update = new SkipMapNodePtr[max_levels+1]; + SkipMapNodePtr curr = + (SkipMapNodePtr) this->header; + int l = level; + SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && CMP(temp->item, item) == 0) + { + delete update; + return temp->cont; + } + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipMapNodePtr)header; + }; + + temp = new RealSkipMapNode (item, def, l); + SkipMapNodePtr *temp_forward = temp->forward; + + do + { + SkipMapNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return temp->cont; +} + +void SkipMap::del( key) +{ + + int l = level; + int curr_level = level; + SkipMapNodePtr *update = new SkipMapNodePtr[max_levels+1]; + SkipMapNodePtr curr = (SkipMapNodePtr)header; + SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipMapNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipMapNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipMapNodePtr SkipMap::rightmost() +{ + SkipMapNodePtr temp; + SkipMapNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipMapNodePtr SkipMap::pred(SkipMapNodePtr t) +{ + SkipMapNodePtr temp, curr = (SkipMapNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipMap::_kill() +{ + SkipMapNode *p = this->header->forward[0]; + + while (p != header) + { + SkipMapNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipMap::clear() +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipMapNodePtr)header; +} + +Pix SkipMap::seek( key) +{ + SkipMapNodePtr temp; + SkipMapNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipMap::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipMap::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipMapNodePtr trail = leftmost(); + SkipMapNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipMapinit::SkipMapinit() +{ + if (!count) + SkipMap::gen = new MLCG(time(0)); + count++; +} + +SkipMapinit::~SkipMapinit() +{ + count--; + if (!count) + delete SkipMap::gen; +} + + diff --git a/gnu/lib/libg++/g++-include/SkipMap.hP b/gnu/lib/libg++/g++-include/SkipMap.hP new file mode 100644 index 0000000000..65766d64c7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipMap.hP @@ -0,0 +1,176 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipMap_h 1 + +#include "..Map.h" + +#include +#include + +class SkipMap; +class RealSkipMapNode; + +class SkipMapNode +{ +friend class SkipMap; + private: + RealSkipMapNode * * forward; + protected: + SkipMapNode(int size); +}; + +class RealSkipMapNode : public SkipMapNode +{ +friend class SkipMap; + private: + item; + cont; + RealSkipMapNode( h, i, int size); +}; + +typedef RealSkipMapNode* SkipMapNodePtr; + +inline SkipMapNode::SkipMapNode(int size) +: forward(new SkipMapNodePtr[size+1]) +{ +} + +inline RealSkipMapNode::RealSkipMapNode( h, i, int size) +: item(h), cont(i), + SkipMapNode(size) +{ +} + +class SkipMap : public Map +{ +friend class SkipMapinit; + protected: + SkipMapNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipMapNodePtr leftmost(); + SkipMapNodePtr rightmost(); + SkipMapNodePtr pred(SkipMapNodePtr t); + SkipMapNodePtr succ(SkipMapNodePtr t); + void _kill(); + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + SkipMap( dflt, long size=DEFAULT_INITIAL_CAPACITY); + SkipMap(SkipMap& a); + ~SkipMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline SkipMap::~SkipMap() +{ + _kill(); + delete header; +} + +inline SkipMapNodePtr SkipMap::leftmost() +{ + return header->forward[0]==header ? 0 : header->forward[0]; +} + +inline Pix SkipMap::first() +{ + return Pix(leftmost()); +} + +inline Pix SkipMap::last() +{ + return Pix(rightmost()); +} + +inline SkipMapNodePtr SkipMap::succ(SkipMapNodePtr t) +{ + return t->forward[0]==header ? 0 : t->forward[0]; +} + +inline void SkipMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipMapNodePtr)i)); +} + +inline void SkipMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipMapNodePtr)i)); +} + +inline & SkipMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipMapNodePtr)i)->item; +} + +inline & SkipMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipMapNodePtr)i)->cont; +} + +inline int SkipMap::contains( key) +{ + return seek(key) != 0; +} + +static class SkipMapinit +{ + public: + SkipMapinit(); + ~SkipMapinit(); + private: + static int count; +} skipMapinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/SkipSet.ccP b/gnu/lib/libg++/g++-include/SkipSet.ccP new file mode 100644 index 0000000000..a1bf33d0fa --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipSet.ccP @@ -0,0 +1,395 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include +#include + +#include ".SkipSet.h" + +MLCG* SkipSet::gen = 0; +int SkipSetinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +SkipSet::SkipSet(long size) +: level(0), + header(new SkipSetNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipSetNodePtr) header; +} + +SkipSet::SkipSet(SkipSet& b) +: level (0), + header (new SkipSetNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipSetNodePtr)header; + + for (SkipSetNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +/* relationals */ + +int SkipSet::operator == (SkipSet& y) +{ + if (count != y.count) + return 0; + else + { + SkipSetNodePtr t = leftmost(); + SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int SkipSet::operator <= (SkipSet& y) +{ + if (count > y.count) + return 0; + else + { + SkipSetNodePtr t = leftmost(); + SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void SkipSet::operator |=(SkipSet& y) +{ + if (&y == this) return; + SkipSetNodePtr u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void SkipSet::operator &= (SkipSet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + SkipSetNodePtr t = leftmost(); + while (t != 0) + { + SkipSetNodePtr s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void SkipSet::operator -=(SkipSet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + SkipSetNodePtr t = leftmost(); + while (t != 0) + { + SkipSetNodePtr s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +Pix SkipSet::add ( i) +{ + SkipSetNodePtr *update = new SkipSetNodePtr[max_levels+1]; + SkipSetNodePtr curr = (SkipSetNodePtr) this->header; + int l = level; + SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, i) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && CMP(temp->item, i) == 0) + return Pix(temp); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipSetNodePtr)header; + }; + + temp = new RealSkipSetNode (i, l); + SkipSetNodePtr *temp_forward = temp->forward; + + do + { + SkipSetNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void SkipSet::del( key) +{ + + int l = level; + int curr_level = level; + SkipSetNodePtr *update = new SkipSetNodePtr[max_levels+1]; + SkipSetNodePtr curr = (SkipSetNodePtr)header; + SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipSetNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipSetNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipSetNodePtr SkipSet::rightmost() +{ + SkipSetNodePtr temp; + SkipSetNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipSetNodePtr SkipSet::pred(SkipSetNodePtr t) +{ + SkipSetNodePtr temp, curr = (SkipSetNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipSet::_kill() +{ + SkipSetNode *p = this->header->forward[0]; + + while (p != header) + { + SkipSetNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipSet::clear() +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipSetNodePtr)header; +} + +Pix SkipSet::seek( key) +{ + SkipSetNodePtr temp; + SkipSetNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipSet::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipSet::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipSetNodePtr trail = leftmost(); + SkipSetNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipSetinit::SkipSetinit() +{ + if (!count) + SkipSet::gen = new MLCG(time(0)); + count++; +} + +SkipSetinit::~SkipSetinit() +{ + count--; + if (!count) + delete SkipSet::gen; +} diff --git a/gnu/lib/libg++/g++-include/SkipSet.hP b/gnu/lib/libg++/g++-include/SkipSet.hP new file mode 100644 index 0000000000..cd95305239 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SkipSet.hP @@ -0,0 +1,187 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipSet_h 1 + +#include ".Set.h" + +#include +#include + +class SkipSet; +class RealSkipSetNode; + +class SkipSetNode +{ +friend class SkipSet; + private: + RealSkipSetNode * * forward; + SkipSetNode(int size); +}; + +class RealSkipSetNode : public SkipSetNode +{ +friend class SkipSet; + private: + item; + RealSkipSetNode( h, int size); +}; + +typedef RealSkipSetNode* SkipSetNodePtr; + +inline SkipSetNode::SkipSetNode(int size) +: forward(new SkipSetNodePtr[size+1]) +{ +} + +inline RealSkipSetNode::RealSkipSetNode( h, int size) +: item(h), + SkipSetNode(size) +{ +} + +class SkipSet : public Set +{ +friend class SkipSetinit; + protected: + SkipSetNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipSetNodePtr leftmost(void); + SkipSetNodePtr rightmost(void); + SkipSetNodePtr pred(SkipSetNodePtr t); + SkipSetNodePtr succ(SkipSetNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + public: + SkipSet(long size=DEFAULT_INITIAL_CAPACITY); + SkipSet(SkipSet& a); + ~SkipSet(); + + Pix add( i); + void del( i); + int contains( i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + & operator () (Pix i); + Pix seek( i); + + Pix last(void); + void prev(Pix& i); + + void operator |= (SkipSet& b); + void operator -= (SkipSet& b); + void operator &= (SkipSet& b); + + int operator == (SkipSet& b); + int operator != (SkipSet& b); + int operator <= (SkipSet& b); + + int OK(void); +}; + +/* + * A little overkill on the inlines. + * + */ + +inline SkipSet::~SkipSet(void) +{ + _kill(); + delete header; +} + +inline int SkipSet::operator != (SkipSet& b) +{ + return ! (*this == b); +} + +inline SkipSetNodePtr SkipSet::leftmost(void) +{ + return header->forward[0]; +} + +inline SkipSetNodePtr SkipSet::succ(SkipSetNodePtr t) +{ + SkipSetNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix SkipSet::first(void) +{ + return Pix(leftmost()); +} + +inline Pix SkipSet::last(void) +{ + return Pix(rightmost()); +} + +inline void SkipSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipSetNodePtr)i)); +} + +inline void SkipSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipSetNodePtr)i)); +} + +inline & SkipSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipSetNodePtr)i)->item; +} + + +inline int SkipSet::contains( key) +{ + return seek(key) != 0; +} + +static class SkipSetinit +{ + public: + SkipSetinit(); + ~SkipSetinit(); + private: + static int count; +} skipSetinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/SplayBag.ccP b/gnu/lib/libg++/g++-include/SplayBag.ccP new file mode 100644 index 0000000000..ff02a992a6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayBag.ccP @@ -0,0 +1,445 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplayBag.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayBag::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayBag::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayBag::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayBag::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + + +Pix SplayBag::seek( key, Pix i) +{ + if (root == 0) return 0; + + SplayNode* t = (SplayNode*) i; + if (t != 0) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + { + t = succ(t); + if (t != 0 && EQ(key, t->item)) + return Pix(t); + else + return 0; + } + else if (cmp < 0) + return 0; + } + + t = root; + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + if (comp != 0) + return 0; + else + { + l = pred(t); + while (l != 0 && EQ(l->item, key)) { t = l; l = pred(l); } + return Pix(t); + } +} + +int SplayBag::nof( item) +{ + int n = 0; + SplayNode* t = (SplayNode*)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && EQ(item, t->item)); + } + return n; +} + +Pix SplayBag::add( item) +{ + ++count; + SplayNode* newnode = new SplayNode(item); + SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = CMP(item, t->item); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void SplayBag::_del(SplayNode* t) +{ + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplayBag::remove( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + while (t != 0) + { + _del(t); + t = (SplayNode*)(seek(key)); + } +} + + +void SplayBag::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayBag::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int SplayBag::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) <= 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/SplayBag.hP b/gnu/lib/libg++/g++-include/SplayBag.hP new file mode 100644 index 0000000000..9d7fcad1dd --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayBag.hP @@ -0,0 +1,144 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayBag_h 1 + +#include ".Bag.h" +#include ".SplayNode.h" + +class SplayBag : public Bag +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + void _del(SplayNode* t); + +public: + SplayBag(); + SplayBag(SplayBag& a); + ~SplayBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline SplayBag::~SplayBag() +{ + _kill(root); +} + +inline SplayBag::SplayBag() +{ + root = 0; + count = 0; +} + +inline SplayBag::SplayBag(SplayBag& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayBag::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayBag::last() +{ + return Pix(rightmost()); +} + +inline void SplayBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplayBag::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayBag::contains( key) +{ + return seek(key) != 0; +} + +inline void SplayBag::del( key) +{ + _del((SplayNode*)(seek(key))); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SplayMap.ccP b/gnu/lib/libg++/g++-include/SplayMap.ccP new file mode 100644 index 0000000000..4be340db0f --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayMap.ccP @@ -0,0 +1,401 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..SplayMap.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayMap::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayMap::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayMap::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayMap::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplayMap::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +& SplayMap::operator [] ( item) +{ + SplayNode* t = root; + if (t == 0) + { + ++count; + root = new SplayNode(item, def); + return root->cont; + } + int comp = CMP(item, t->item); + if (comp == 0) + return t->cont; + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return root->cont; +} + +void SplayMap::del( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplayMap::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayMap::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, t->cont, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + + +int SplayMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/SplayMap.hP b/gnu/lib/libg++/g++-include/SplayMap.hP new file mode 100644 index 0000000000..ced95378ab --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayMap.hP @@ -0,0 +1,154 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayMap_h 1 + +#include "..Map.h" + +#ifndef _SplayNode +#define _SplayNode 1 + +struct SplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; + item; + cont; + SplayNode( h, c, + SplayNode* l=0, + SplayNode* r=0); + ~SplayNode(); +}; + + +inline SplayNode::SplayNode( h, c, + SplayNode* l, + SplayNode* r) + :item(h), cont(c), lt(l), rt(r), par(0) {} + +inline SplayNode::~SplayNode() {} + +typedef SplayNode* SplayNodePtr; + +#endif + +class SplayMap : public Map +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplayMap( dflt); + SplayMap(SplayMap& a); + ~SplayMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline SplayMap::~SplayMap() +{ + _kill(root); +} + +inline SplayMap::SplayMap( dflt) :Map(dflt) +{ + root = 0; +} + +inline SplayMap::SplayMap(SplayMap& b) :Map(b.def) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayMap::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayMap::last() +{ + return Pix(rightmost()); +} + +inline void SplayMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline & SplayMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->cont; +} + +inline void SplayMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SplayNode.ccP b/gnu/lib/libg++/g++-include/SplayNode.ccP new file mode 100644 index 0000000000..9dfb1d8c06 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SplayNode.h" diff --git a/gnu/lib/libg++/g++-include/SplayNode.hP b/gnu/lib/libg++/g++-include/SplayNode.hP new file mode 100644 index 0000000000..a196861fc9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayNode.hP @@ -0,0 +1,44 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _SplayNode +#define _SplayNode 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include ".defs.h" + +struct SplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; + item; + SplayNode( h, SplayNode* l=0, SplayNode* r=0); + ~SplayNode(); +}; + + +inline SplayNode::SplayNode( h, SplayNode* l, SplayNode* r) +:item(h), lt(l), rt(r), par(0) {} + +inline SplayNode::~SplayNode() {} + +typedef SplayNode* SplayNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/SplayPQ.ccP b/gnu/lib/libg++/g++-include/SplayPQ.ccP new file mode 100644 index 0000000000..0740cd9a93 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayPQ.ccP @@ -0,0 +1,523 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplayPQ.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayPQ::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayPQ::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayPQ::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayPQ::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplayPQ::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +Pix SplayPQ::enq( item) +{ + ++count; + SplayNode* newnode = new SplayNode(item); + SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = CMP(item, t->item); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + + +void SplayPQ::del(Pix pix) +{ + SplayNode* t = (SplayNode*)pix; + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + +& SplayPQ::front() +{ + if (root == 0) + error ("min: empty tree\n"); +// else + { + SplayNode* t = root; + SplayNode* l = root->lt; + for(;;) + { + if (l == 0) + { + root = t; + root->par = 0; + return root->item; + } + else + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + l->rt = t; t->par = l; + t = l; + l = l->lt; + } + } + } +} + +void SplayPQ::del_front() +{ + if (root != 0) + { + --count; + SplayNode* t = root; + SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + delete t; + } + else + { + for(;;) + { + SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + delete l; + break; + } + else + { + SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + delete ll; + break; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + + SplayPQ::deq() +{ + if (root == 0) + error("deq: empty tree"); +// else + { + --count; + SplayNode* t = root; + SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + res = t->item; + delete t; + return res; + } + else + { + for(;;) + { + SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + res = l->item; + delete l; + return res; + } + else + { + SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + res = ll->item; + delete ll; + return res; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + + +void SplayPQ::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayPQ::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int SplayPQ::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/SplayPQ.hP b/gnu/lib/libg++/g++-include/SplayPQ.hP new file mode 100644 index 0000000000..c75c4a0529 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplayPQ.hP @@ -0,0 +1,123 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayPQ_h 1 + +#include ".PQ.h" +#include ".SplayNode.h" + +class SplayPQ : public PQ +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplayPQ(); + SplayPQ(SplayPQ& a); + virtual ~SplayPQ(); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + Pix last(); + void next(Pix& i); + void prev(Pix& i); + & operator () (Pix i); + void del(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + + +inline SplayPQ::~SplayPQ() +{ + _kill(root); +} + +inline SplayPQ::SplayPQ() +{ + root = 0; + count = 0; +} + +inline SplayPQ::SplayPQ(SplayPQ& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayPQ::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayPQ::last() +{ + return Pix(rightmost()); +} + +inline void SplayPQ::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayPQ::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayPQ::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplayPQ::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayPQ::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/SplaySet.ccP b/gnu/lib/libg++/g++-include/SplaySet.ccP new file mode 100644 index 0000000000..bba5601c7e --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplaySet.ccP @@ -0,0 +1,499 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplaySet.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplaySet::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplaySet::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplaySet::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplaySet::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplaySet::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + + +Pix SplaySet::add( item) +{ + SplayNode* t = root; + if (t == 0) + { + ++count; + root = new SplayNode(item); + return Pix(root); + } + int comp = CMP(item, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void SplaySet::del( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplaySet::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplaySet::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +/* relationals */ + +int SplaySet::operator == (SplaySet& y) +{ + if (count != y.count) + return 0; + else + { + SplayNode* t = leftmost(); + SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int SplaySet::operator <= (SplaySet& y) +{ + if (count > y.count) + return 0; + else + { + SplayNode* t = leftmost(); + SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void SplaySet::operator |=(SplaySet& y) +{ + if (&y == this) return; + SplayNode* u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void SplaySet::operator &= (SplaySet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + SplayNode* t = leftmost(); + while (t != 0) + { + SplayNode* s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void SplaySet::operator -=(SplaySet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + SplayNode* t = leftmost(); + while (t != 0) + { + SplayNode* s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +int SplaySet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/SplaySet.hP b/gnu/lib/libg++/g++-include/SplaySet.hP new file mode 100644 index 0000000000..cf50b97554 --- /dev/null +++ b/gnu/lib/libg++/g++-include/SplaySet.hP @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplaySet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplaySet_h 1 + +#include ".Set.h" +#include ".SplayNode.h" + +class SplaySet : public Set +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplaySet(); + SplaySet(SplaySet& a); + ~SplaySet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + void operator |= (SplaySet& b); + void operator -= (SplaySet& b); + void operator &= (SplaySet& b); + + int operator == (SplaySet& b); + int operator != (SplaySet& b); + int operator <= (SplaySet& b); + + int OK(); +}; + + +inline SplaySet::~SplaySet() +{ + _kill(root); +} + +inline SplaySet::SplaySet() +{ + root = 0; + count = 0; +} + +inline SplaySet::SplaySet(SplaySet& b) +{ + count = b.count; + root = _copy(b.root); +} + + +inline int SplaySet::operator != (SplaySet& b) +{ + return ! (*this == b); +} + +inline Pix SplaySet::first() +{ + return Pix(leftmost()); +} + +inline Pix SplaySet::last() +{ + return Pix(rightmost()); +} + +inline void SplaySet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplaySet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplaySet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplaySet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplaySet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Stack.ccP b/gnu/lib/libg++/g++-include/Stack.ccP new file mode 100644 index 0000000000..efb6b8edbd --- /dev/null +++ b/gnu/lib/libg++/g++-include/Stack.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Stack.h" + +Stack::~Stack() {} + +void Stack::error(const char* msg) +{ + (*lib_error_handler)("Stack", msg); +} diff --git a/gnu/lib/libg++/g++-include/Stack.hP b/gnu/lib/libg++/g++-include/Stack.hP new file mode 100644 index 0000000000..37acb2fac5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Stack.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Stack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Stack_h + +#include + +#include ".defs.h" + +class Stack +{ +public: + Stack() { } + virtual ~Stack(); + + virtual void push( item) = 0; + virtual pop() = 0; + virtual & top() = 0; + virtual void del_top() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + virtual void clear() = 0; + + void error(const char*); + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/VHBag.ccP b/gnu/lib/libg++/g++-include/VHBag.ccP new file mode 100644 index 0000000000..81a20eb140 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHBag.ccP @@ -0,0 +1,264 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".VHBag.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHBag::VHBag(unsigned int sz) +{ + tab = new [size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +VHBag::VHBag(VHBag& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHBag::seek( key, Pix p) +{ + * t = (*) p; + if (t == 0 || !EQ(*t, key)) + { + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } + else + { + int seent = 0; + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (&tab[h] == t) + seent = 1; + else if (seent && status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } +} + +int VHBag::nof( item) +{ + int n = 0; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + unsigned int firsth = size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return n; + else if (h != firsth && status[h] == VALIDCELL && EQ(item, tab[h])) + { + ++n; + if (firsth >= size) + firsth = h; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return n; +} + + +Pix VHBag::add( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); +} + + +void VHBag::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void VHBag::remove( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void VHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHBag::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VHBag::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHBag::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VHBag::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/VHBag.hP b/gnu/lib/libg++/g++-include/VHBag.hP new file mode 100644 index 0000000000..72c774a559 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHBag.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHBag_h 1 + +#include ".Bag.h" + + +class VHBag : public Bag +{ +protected: + * tab; + char* status; + unsigned int size; + +public: + VHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + VHBag(VHBag& a); + ~VHBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline VHBag::~VHBag() +{ + delete [] tab; + delete status; +} + + +inline int VHBag::capacity() +{ + return size; +} + +inline int VHBag::contains( key) +{ + return seek(key) != 0; +} + +inline & VHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/VHMap.ccP b/gnu/lib/libg++/g++-include/VHMap.ccP new file mode 100644 index 0000000000..d6b60e997a --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHMap.ccP @@ -0,0 +1,210 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "..VHMap.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHMap::VHMap( dflt, unsigned int sz) + :Map(dflt) +{ + tab = new [size = sz]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; +} + +VHMap::VHMap(VHMap& a) : Map(a.def) +{ + tab = new [size = a.size]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHMap::seek( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +& VHMap::operator []( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + ++count; + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + cont[bestspot] = def; + return cont[bestspot]; + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (EQ(tab[h],item)) + return cont[h]; + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + + ++count; + status[bestspot] = VALIDCELL; + tab[bestspot] = item; + cont[bestspot] = def; + return cont[bestspot]; +} + + +void VHMap::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void VHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHMap::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + * oldcont = cont; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) + if (oldstatus[i] == VALIDCELL) + (*this)[oldtab[i]] = oldcont[i]; + delete [] oldtab; + delete [] oldcont; + delete oldstatus; +} + +Pix VHMap::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHMap::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VHMap::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/VHMap.hP b/gnu/lib/libg++/g++-include/VHMap.hP new file mode 100644 index 0000000000..ac8fe4d219 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHMap.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHMap_h 1 + +#include "..Map.h" + + +class VHMap : public Map +{ +protected: + * tab; + * cont; + char* status; + unsigned int size; + +public: + VHMap( dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + VHMap(VHMap& a); + ~VHMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + +inline VHMap::~VHMap() +{ + delete [] tab; + delete [] cont; + delete [] status; +} + +inline int VHMap::contains( key) +{ + return seek(key) != 0; +} + +inline & VHMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +inline & VHMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return cont[((unsigned)(i) - (unsigned)(tab)) / sizeof()]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/VHSet.ccP b/gnu/lib/libg++/g++-include/VHSet.ccP new file mode 100644 index 0000000000..a78b319834 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHSet.ccP @@ -0,0 +1,263 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".VHSet.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHSet::VHSet(unsigned int sz) +{ + tab = new [size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +VHSet::VHSet(VHSet& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHSet::seek( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +Pix VHSet::add( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (EQ(tab[h],item)) + return Pix(&tab[h]); + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + +} + + +void VHSet::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void VHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHSet::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VHSet::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHSet::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + +int VHSet:: operator == (VHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int VHSet::operator <= (VHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void VHSet::operator |= (VHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void VHSet::operator &= (VHSet& b) +{ + if (&b == this || count == 0) + return; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void VHSet::operator -= (VHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int VHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/VHSet.hP b/gnu/lib/libg++/g++-include/VHSet.hP new file mode 100644 index 0000000000..b7b3a3578c --- /dev/null +++ b/gnu/lib/libg++/g++-include/VHSet.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHSet_h 1 + +#include ".Set.h" + + + +class VHSet : public Set +{ +protected: + * tab; + char* status; + unsigned int size; + +public: + VHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + VHSet(VHSet& a); + ~VHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (VHSet& b); + void operator -= (VHSet& b); + void operator &= (VHSet& b); + + int operator == (VHSet& b); + int operator != (VHSet& b); + int operator <= (VHSet& b); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline VHSet::~VHSet() +{ + delete [] tab; + delete status; +} + + +inline int VHSet::capacity() +{ + return size; +} + +inline int VHSet::contains( key) +{ + return seek(key) != 0; +} + +inline & VHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +inline int VHSet::operator != (VHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/VOHSet.ccP b/gnu/lib/libg++/g++-include/VOHSet.ccP new file mode 100644 index 0000000000..c5d4557a4c --- /dev/null +++ b/gnu/lib/libg++/g++-include/VOHSet.ccP @@ -0,0 +1,308 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VOHSet.h" + + +/* codes for status fields */ +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VOHSet::VOHSet(int sz) +{ +// The size of the hash table is always the smallest power of 2 >= the size +// indicated by the user. This allows several optimizations, including +// the use of actual double hashing and elimination of the mod instruction. + + size = 1; + while (size < sz) size <<= 1; + tab = new [size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +VOHSet::VOHSet(VOHSet& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + +Pix VOHSet::seek( key) +{ +// Uses ordered double hashing to perform a search of the table. +// This greatly speeds up the average-case time for an unsuccessful search. + + unsigned hashval = HASH(key); + + // We can avoid the mod operation since size is a power of 2. + unsigned h = hashval & (size - 1); + + // The increment must be odd, since all odd numbers are relatively + // prime to a power of 2!! + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + // There is always at least 1 empty cell, so this loop is guaranteed to halt! + while (status[h] != EMPTYCELL) + { + int cmp = CMP (key, tab[h]); + if (cmp == 0) + { + if (status[h] == VALIDCELL) + return Pix(&tab[h]); + else + return 0; + } + else if (cmp > 0) + return 0; + else + h = ((h + inc) & (size - 1)); + } + return 0; +} + +// This adds an item if it doesn't already exist. By performing the initial +// comparison we assure that the table always contains at least 1 empty +// spot. This speeds up later searching by a constant factor. +// The insertion algorithm uses ordered double hashing. See Standish's +// 1980 ``Data Structure's Techniques'' book for details. + +Pix VOHSet::add( x) +{ + if (size <= cnt+1) + resize(); + + unsigned hashval = HASH(x); + unsigned h = hashval & (size - 1); + + if (status[h] != VALIDCELL) // save some work if possible + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = x; + status[h] = VALIDCELL; + return Pix(&tab[h]); + } + int cmp = CMP(x, tab[h]); + if (cmp == 0) + return Pix(&tab[h]); + + item = x; + Pix mypix = 0; + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + for (;;) + { + if (cmp < 0) + { + temp = tab[h]; + tab[h] = item; + item = temp; + if (mypix == 0) mypix = Pix(&tab[h]); + inc = ((((HASH(item) / size) << 1) + 1) & (size - 1)); + h = ((h + inc) & (size - 1)); + if (status[h] != EMPTYCELL) cmp = CMP(item, tab[h]); + } + else + h = ((h + inc) & (size - 1)); + if (status[h] != VALIDCELL) + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = item; + status[h] = VALIDCELL; + return (mypix == 0)? Pix(&tab[h]) : mypix; + } + } +} + + +void VOHSet::del( key) +{ +// This performs a deletion by marking the item's status field. +// Note that we only decrease the count, *not* the cnt, since this +// would cause trouble for subsequent steps in the algorithm. See +// Reingold and Hanson's ``Data Structure's'' book for a justification +// of this approach. + + unsigned hashval = HASH(key); + unsigned h = hashval & (size - 1); + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + while (status[h] != EMPTYCELL) + { + int cmp = CMP(key, tab[h]); + if (cmp > 0) + h = ((h + inc) & (size - 1)); + else if (status[h] == VALIDCELL && cmp == 0) + { + status[h] = DELETEDCELL; + count--; + return; + } + else + return; + } +} + +void VOHSet::clear() +{ + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +void VOHSet::resize(int newsize) +{ + if (newsize <= count) + newsize = count; + int s = 1; + while (s <= newsize) s <<= 1; + newsize = s; + + * oldtab = tab; + char* oldstatus = status; + int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VOHSet::first() +{ + for (int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VOHSet::next(Pix& i) +{ + if (i == 0) return; + int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VOHSet:: operator == (VOHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int VOHSet:: operator != (VOHSet& b) +{ + return !(*this == b); +} + +int VOHSet::operator <= (VOHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void VOHSet::operator |= (VOHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void VOHSet::operator &= (VOHSet& b) +{ + if (&b == this || count == 0) + return; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void VOHSet::operator -= (VOHSet& b) +{ + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int VOHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} + + + diff --git a/gnu/lib/libg++/g++-include/VOHSet.hP b/gnu/lib/libg++/g++-include/VOHSet.hP new file mode 100644 index 0000000000..94decaad12 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VOHSet.hP @@ -0,0 +1,88 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VOHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VOHSet_h 1 + +#include ".Set.h" + + + +class VOHSet : public Set +{ + * tab; + char* status; + int size; + int cnt; // keeps track of VALIDCELLs and DELETEDCELLs + +public: + VOHSet(int sz = DEFAULT_INITIAL_CAPACITY); + VOHSet(VOHSet&); + ~VOHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (VOHSet& b); + void operator -= (VOHSet& b); + void operator &= (VOHSet& b); + + int operator == (VOHSet& b); + int operator != (VOHSet& b); + int operator <= (VOHSet& b); + + int capacity(); + void resize(int newsize = 0); + + int OK(); +}; + + +inline VOHSet::~VOHSet() +{ + delete [] tab; + delete status; +} + + +inline int VOHSet::contains( key) +{ + return seek(key) != 0; +} + + +inline & VOHSet::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return *((*)p); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/VQueue.ccP b/gnu/lib/libg++/g++-include/VQueue.ccP new file mode 100644 index 0000000000..1181b3f50d --- /dev/null +++ b/gnu/lib/libg++/g++-include/VQueue.ccP @@ -0,0 +1,83 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VQueue.h" + +VQueue::VQueue(VQueue& b) +:size(b.size), cnt(b.cnt), inp(b.inp), outp(b.outp), s(new [b.size]) +{ + int j = outp; + for (int i = 0; i < cnt; ++i) + { + s[j] = b.s[j]; + if (++j == size) j = 0; + } +} + +void VQueue::operator = (VQueue& b) +{ + if (&b == this) return; + if (size != b.size) + { + delete [] s; + s = new [b.size]; + size = b.size; + } + inp = b.inp; outp = b.outp; cnt = b.cnt; + int j = outp; + for (int i = 0; i < cnt; ++i) + { + s[j] = b.s[j]; + if (++j == size) j = 0; + } +} + + +void VQueue::resize(int newsz) +{ + if (newsz < cnt) + error("resize: new size too small"); + * news = new [newsz]; + int j = outp; + for (int i = 0; i < cnt; ++i) + { + news[i] = s[j]; + if (++j == size) j = 0; + } + inp = j; + outp = 0; + delete [] s; + s = news; + size = newsz; +} + +int VQueue::OK() +{ + int v = s != 0; // have space + v &= size >= 0; // a legal size + v &= inp >= 0 && inp <= size; // pointers with bounds + v &= outp >= 0 && outp <= size; + int c = (size + inp - outp) % size; + v &= cnt == size || cnt == c; // correct count + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/VQueue.hP b/gnu/lib/libg++/g++-include/VQueue.hP new file mode 100644 index 0000000000..cce2c85d24 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VQueue.hP @@ -0,0 +1,130 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VQueue_h 1 + +#include ".Queue.h" + +class VQueue : public Queue +{ +protected: + int size; + int cnt; + int inp; + int outp; + * s; + +public: + + VQueue(int sz = DEFAULT_INITIAL_CAPACITY); + VQueue(VQueue&); + ~VQueue(); + + void operator = (VQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + int length(); + int empty(); + int full(); + + int capacity(); + void resize(int sz); + void clear(); + + int OK(); +}; + + +inline VQueue::VQueue(int sz) +{ + s = new [size = sz]; + cnt = inp = outp = 0; +} + +inline VQueue::~VQueue() +{ + delete [] s; +} + +inline void VQueue::clear() +{ + inp = outp = 0; + cnt = 0; +} + +inline int VQueue::empty() +{ + return cnt <= 0; +} + +inline int VQueue::capacity() +{ + return size; +} + +inline int VQueue::full() +{ + return cnt >= size; +} + +inline int VQueue::length() +{ + return cnt; +} + +inline void VQueue::enq( item) +{ + if (cnt >= size) error("enq to full Queue."); + ++cnt; + s[inp] = item; + if (++inp == size) inp = 0; +} + +inline VQueue::deq() +{ + if (cnt <= 0) error("deq from empty Queue."); + --cnt; + int i = outp; + if (++outp == size) outp = 0; + return s[i]; +} + + +inline void VQueue::del_front() +{ + if (cnt <= 0) error("delete from empty Queue."); + --cnt; + if (++outp == size) outp = 0; +} + +inline & VQueue::front() +{ + if (empty()) error("top from empty Queue."); + return s[outp]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/VStack.ccP b/gnu/lib/libg++/g++-include/VStack.ccP new file mode 100644 index 0000000000..5203d51341 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VStack.ccP @@ -0,0 +1,66 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VStack.h" + +// error handling + + +VStack::VStack(VStack& b) +:size(b.size), ptr(b.ptr), s(new [b.size]) +{ + for (int i = 0; i < ptr; ++i) s[i] = b.s[i]; +} + +void VStack::operator = (VStack& b) +{ + if (&b == this) return; + if (size < b.ptr) + { + delete [] s; + s = new [b.size]; + size = b.size; + } + ptr = b.ptr; + for (int i = 0; i < ptr; ++i) s[i] = b.s[i]; +} + + +void VStack::resize(int newsz) +{ + if (newsz < ptr) error("resize: new size too small"); + * news = new [newsz]; + for (int i = 0; i < ptr; ++i) news[i] = s[i]; + delete [] s; + s = news; + size = newsz; +} + +int VStack::OK() +{ + int v = s != 0; // have space + v &= size >= 0; // a legal size + v &= ptr <= size; // ptr within bounds + v &= ptr >= 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/VStack.hP b/gnu/lib/libg++/g++-include/VStack.hP new file mode 100644 index 0000000000..c8190bf064 --- /dev/null +++ b/gnu/lib/libg++/g++-include/VStack.hP @@ -0,0 +1,120 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VStack_h 1 + +#include ".Stack.h" + +class VStack : public Stack +{ +protected: + int size; + int ptr; + * s; + +public: + + VStack(int sz = DEFAULT_INITIAL_CAPACITY); + VStack(VStack&); + ~VStack(); + + void operator = (VStack&); + void push( item); + pop(); + & top(); + void del_top(); + + int length(); + int empty(); + int full(); + void clear(); + + void resize(int sz); + int capacity(); + + int OK(); +}; + + +inline VStack::VStack(int sz) +{ + s = new [size = sz]; + ptr = 0; +} + +inline VStack::~VStack() +{ + delete [] s; +} + +inline void VStack::clear() +{ + ptr = 0; +} + +inline int VStack::capacity() +{ + return size; +} + +inline int VStack::empty() +{ + return ptr == 0; +} + +inline int VStack::full() +{ + return ptr == size; +} + +inline int VStack::length() +{ + return ptr; +} + +inline void VStack::push( item) +{ + if (full()) error("push to full stack."); + s[ptr++] = item; +} + +inline VStack::pop() +{ + if (empty()) error("pop from empty stack."); + return s[--ptr]; +} + + +inline void VStack::del_top() +{ + if (empty()) error("del_top from empty stack."); + --ptr; +} + +inline & VStack::top() +{ + if (empty()) error("top from empty stack."); + return s[ptr-1]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/Vec.ccP b/gnu/lib/libg++/g++-include/Vec.ccP new file mode 100644 index 0000000000..c9cbfb2109 --- /dev/null +++ b/gnu/lib/libg++/g++-include/Vec.ccP @@ -0,0 +1,470 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".Vec.h" + +// error handling + + +void default_Vec_error_handler(const char* msg) +{ + cerr << "Fatal Vec error. " << msg << "\n"; + exit(1); +} + +one_arg_error_handler_t Vec_error_handler = default_Vec_error_handler; + +one_arg_error_handler_t set_Vec_error_handler(one_arg_error_handler_t f) +{ + one_arg_error_handler_t old = Vec_error_handler; + Vec_error_handler = f; + return old; +} + +void Vec::error(const char* msg) +{ + (*Vec_error_handler)(msg); +} + +void Vec::range_error() +{ + (*Vec_error_handler)("Index out of range."); +} + +Vec::Vec(Vec& v) +{ + s = new [len = v.len]; + * top = &(s[len]); + * t = s; + * u = v.s; + while (t < top) *t++ = *u++; +} + +Vec::Vec(int l, fill_value) +{ + s = new [len = l]; + * top = &(s[len]); + * t = s; + while (t < top) *t++ = fill_value; +} + + +Vec& Vec::operator = (Vec& v) +{ + if (this != &v) + { + delete [] s; + s = new [len = v.len]; + * top = &(s[len]); + * t = s; + * u = v.s; + while (t < top) *t++ = *u++; + } + return *this; +} + +void Vec::apply(Procedure f) +{ + * top = &(s[len]); + * t = s; + while (t < top) (*f)(*t++); +} + +// can't just realloc since there may be need for constructors/destructors +void Vec::resize(int newl) +{ + * news = new [newl]; + * p = news; + int minl = (len < newl)? len : newl; + * top = &(s[minl]); + * t = s; + while (t < top) *p++ = *t++; + delete [] s; + s = news; + len = newl; +} + +Vec concat(Vec & a, Vec & b) +{ + int newl = a.len + b.len; + * news = new [newl]; + * p = news; + * top = &(a.s[a.len]); + * t = a.s; + while (t < top) *p++ = *t++; + top = &(b.s[b.len]); + t = b.s; + while (t < top) *p++ = *t++; + return Vec(newl, news); +} + + +Vec combine(Combiner f, Vec& a, Vec& b) +{ + int newl = (a.len < b.len)? a.len : b.len; + * news = new [newl]; + * p = news; + * top = &(a.s[newl]); + * t = a.s; + * u = b.s; + while (t < top) *p++ = (*f)(*t++, *u++); + return Vec(newl, news); +} + + Vec::reduce(Combiner f, base) +{ + r = base; + * top = &(s[len]); + * t = s; + while (t < top) r = (*f)(r, *t++); + return r; +} + +Vec reverse(Vec& a) +{ + * news = new [a.len]; + if (a.len != 0) + { + * lo = news; + * hi = &(news[a.len - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } + return Vec(a.len, news); +} + +void Vec::reverse() +{ + if (len != 0) + { + * lo = s; + * hi = &(s[len - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } +} + +int Vec::index( targ) +{ + for (int i = 0; i < len; ++i) if (EQ(targ, s[i])) return i; + return -1; +} + +Vec map(Mapper f, Vec& a) +{ + * news = new [a.len]; + * p = news; + * top = &(a.s[a.len]); + * t = a.s; + while(t < top) *p++ = (*f)(*t++); + return Vec(a.len, news); +} + +int operator == (Vec& a, Vec& b) +{ + if (a.len != b.len) + return 0; + * top = &(a.s[a.len]); + * t = a.s; + * u = b.s; + while (t < top) if (!(EQ(*t++, *u++))) return 0; + return 1; +} + +void Vec::fill( val, int from, int n) +{ + int to; + if (n < 0) + to = len - 1; + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *t++ = val; +} + +Vec Vec::at(int from, int n) +{ + int to; + if (n < 0) + { + n = len - from; + to = len - 1; + } + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * news = new [n]; + * p = news; + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *p++ = *t++; + return Vec(n, news); +} + +Vec merge(Vec & a, Vec & b, Comparator f) +{ + int newl = a.len + b.len; + * news = new [newl]; + * p = news; + * topa = &(a.s[a.len]); + * as = a.s; + * topb = &(b.s[b.len]); + * bs = b.s; + + for (;;) + { + if (as >= topa) + { + while (bs < topb) *p++ = *bs++; + break; + } + else if (bs >= topb) + { + while (as < topa) *p++ = *as++; + break; + } + else if ((*f)(*as, *bs) <= 0) + *p++ = *as++; + else + *p++ = *bs++; + } + return Vec(newl, news); +} + +static int gsort(*, int, Comparator); + +void Vec::sort (Comparator compar) +{ + gsort(s, len, compar); +} + + +// An adaptation of Schmidt's new quicksort + +static inline void SWAP(* A, * B) +{ + tmp = *A; *A = *B; *B = tmp; +} + +/* This should be replaced by a standard ANSI macro. */ +#define BYTES_PER_WORD 8 +#define BYTES_PER_LONG 4 + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ + +#define STACK_SIZE (BYTES_PER_WORD * BYTES_PER_LONG) +#define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0) +#define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0) +#define STACK_NOT_EMPTY (stack < top) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that + store the next array partition to sort. To save time, this + maximum amount of space required to store an array of + MAX_INT is allocated on the stack. Assuming a 32-bit integer, + this needs only 32 * sizeof (stack_node) == 136 bits. Pretty + cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segements. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (n) + stack size is needed! */ + +static int gsort ( *base_ptr, int total_elems, Comparator cmp) +{ +/* Stack node declarations used to store unfulfilled partition obligations. */ + struct stack_node { *lo; *hi; }; + pivot_buffer; + int max_thresh = MAX_THRESH; + + if (total_elems > MAX_THRESH) + { + *lo = base_ptr; + *hi = lo + (total_elems - 1); + *left_ptr; + *right_ptr; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) + { + { + *pivot = &pivot_buffer; + { + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ + + *mid = lo + ((hi - lo) >> 1); + + if ((*cmp) (*mid, *lo) < 0) + SWAP (mid, lo); + if ((*cmp) (*hi, *mid) < 0) + { + SWAP (mid, hi); + if ((*cmp) (*mid, *lo) < 0) + SWAP (mid, lo); + } + *pivot = *mid; + pivot = &pivot_buffer; + } + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) (*left_ptr, *pivot) < 0) + left_ptr += 1; + + while ((*cmp) (*pivot, *right_ptr) < 0) + right_ptr -= 1; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr); + left_ptr += 1; + right_ptr -= 1; + } + else if (left_ptr == right_ptr) + { + left_ptr += 1; + right_ptr -= 1; + break; + } + } + while (left_ptr <= right_ptr); + + } + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((right_ptr - lo) <= max_thresh) + { + if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ + POP (lo, hi); + else /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */ + { + PUSH (lo, right_ptr); + lo = left_ptr; + } + else /* Push larger right partition indices. */ + { + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + + { + *end_ptr = base_ptr + 1 * (total_elems - 1); + *run_ptr; + *tmp_ptr = base_ptr; + *thresh = (end_ptr < (base_ptr + max_thresh))? + end_ptr : (base_ptr + max_thresh); + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr += 1) + if ((*cmp) (*run_ptr, *tmp_ptr) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr); + + /* Insertion sort, running from left-hand-side up to `right-hand-side.' + Pretty much straight out of the original GNU qsort routine. */ + + for (run_ptr = base_ptr + 1; (tmp_ptr = run_ptr += 1) <= end_ptr; ) + { + + while ((*cmp) (*run_ptr, *(tmp_ptr -= 1)) < 0) + ; + + if ((tmp_ptr += 1) != run_ptr) + { + *trav; + + for (trav = run_ptr + 1; --trav >= run_ptr;) + { + c = *trav; + *hi, *lo; + + for (hi = lo = trav; (lo -= 1) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + + } + } + return 1; +} diff --git a/gnu/lib/libg++/g++-include/Vec.hP b/gnu/lib/libg++/g++-include/Vec.hP new file mode 100644 index 0000000000..97ff3f5fef --- /dev/null +++ b/gnu/lib/libg++/g++-include/Vec.hP @@ -0,0 +1,135 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Vec_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Vec_h 1 + +#include +#include ".defs.h" + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)(); +typedef (*Mapper)(); +typedef (*Combiner)(, ); +typedef int (*Predicate)(); +typedef int (*Comparator)(, ); +#endif + + +class Vec +{ +protected: + int len; + *s; + + Vec(int l, * d); +public: + Vec (); + Vec (int l); + Vec (int l, fill_value); + Vec (Vec&); + ~Vec (); + + Vec & operator = (Vec & a); + Vec at(int from = 0, int n = -1); + + int capacity(); + void resize(int newlen); + + & operator [] (int n); + & elem(int n); + + friend Vec concat(Vec & a, Vec & b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec & a); + + void reverse(); + void sort(Comparator f); + void fill( val, int from = 0, int n = -1); + + void apply(Procedure f); + reduce(Combiner f, base); + int index( targ); + + friend int operator == (Vec& a, Vec& b); + friend int operator != (Vec& a, Vec& b); + + void error(const char* msg); + void range_error(); +}; + +extern void default_Vec_error_handler(const char*); +extern one_arg_error_handler_t Vec_error_handler; + +extern one_arg_error_handler_t + set_Vec_error_handler(one_arg_error_handler_t f); + + +inline Vec::Vec() +{ + len = 0; s = 0; +} + +inline Vec::Vec(int l) +{ + s = new [len = l]; +} + + +inline Vec::Vec(int l, * d) :len(l), s(d) {} + + +inline Vec::~Vec() +{ + delete [] s; +} + + +inline & Vec::operator [] (int n) +{ + if ((unsigned)n >= (unsigned)len) + range_error(); + return s[n]; +} + +inline & Vec::elem(int n) +{ + return s[n]; +} + + +inline int Vec::capacity() +{ + return len; +} + + + +inline int operator != (Vec& a, Vec& b) +{ + return !(a == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPBag.ccP b/gnu/lib/libg++/g++-include/XPBag.ccP new file mode 100644 index 0000000000..76dc35cf39 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPBag.ccP @@ -0,0 +1,72 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPBag.h" + +int XPBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPBag::seek( item, Pix i) +{ + if (i == 0) i = p.first(); else next(i); + for (; i != 0; p.next(i)) if (EQ(p(i), item)) return i; + return 0; +} + +int XPBag::nof( item) +{ + int n = 0; + for (int i = p.low(); i < p.fence(); p.next(i)) if (EQ(p[i], item)) ++n; + return n; +} + +void XPBag::del( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + return; + } + } +} + +void XPBag::remove( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + } + } +} + diff --git a/gnu/lib/libg++/g++-include/XPBag.hP b/gnu/lib/libg++/g++-include/XPBag.hP new file mode 100644 index 0000000000..296a59082d --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPBag.hP @@ -0,0 +1,98 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPBag_h 1 + +#include ".Bag.h" +#include ".XPlex.h" + +class XPBag : public Bag +{ +protected: + XPlex p; + +public: + XPBag(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPBag(const XPBag&); + + Pix add( item); + void del( item); +#undef remove + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline XPBag::XPBag(int chunksize) + : p(chunksize) { count = 0; } + +inline XPBag::XPBag(const XPBag& s) : p(s.p) { count = s.count; } + +inline Pix XPBag::first() +{ + return p.first(); +} + +inline void XPBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void XPBag::clear() +{ + count = 0; p.clear(); +} + +inline int XPBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline Pix XPBag::add( item) +{ + ++count; + return p.index_to_Pix(p.add_high(item)); +} + +inline int XPBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPDeque.ccP b/gnu/lib/libg++/g++-include/XPDeque.ccP new file mode 100644 index 0000000000..6b363d9bdc --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPDeque.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPDeque.h" diff --git a/gnu/lib/libg++/g++-include/XPDeque.hP b/gnu/lib/libg++/g++-include/XPDeque.hP new file mode 100644 index 0000000000..b8e7c8268f --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPDeque.hP @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPDeque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPDeque_h + +#include ".XPlex.h" +#include ".Deque.h" + +class XPDeque : public Deque +{ + XPlex p; + +public: + XPDeque(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPDeque(const XPDeque& d); + ~XPDeque(); + + void operator = (const XPDeque&); + + void push( item); // insert at front + void enq( item); // insert at rear + + & front(); + & rear(); + + deq(); + void del_front(); + void del_rear(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline XPDeque::XPDeque(int chunksize) + : p(chunksize) {} +inline XPDeque::XPDeque(const XPDeque& d) : p(d.p) {} + +inline XPDeque::~XPDeque() {} + +inline void XPDeque::push(item) +{ + p.add_low(item); +} + +inline void XPDeque::enq(item) +{ + p.add_high(item); +} + +inline XPDeque::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & XPDeque::front() +{ + return p.low_element(); +} + +inline & XPDeque::rear() +{ + return p.high_element(); +} + +inline void XPDeque::del_front() +{ + p.del_low(); +} + +inline void XPDeque::del_rear() +{ + p.del_high(); +} + +inline void XPDeque::operator =(const XPDeque& s) +{ + p.operator = (s.p); +} + + +inline int XPDeque::empty() +{ + return p.empty(); +} + +inline int XPDeque::full() +{ + return p.full(); +} + +inline int XPDeque::length() +{ + return p.length(); +} + +inline int XPDeque::OK() +{ + return p.OK(); +} + +inline void XPDeque::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPPQ.ccP b/gnu/lib/libg++/g++-include/XPPQ.ccP new file mode 100644 index 0000000000..41515a39bb --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPPQ.ccP @@ -0,0 +1,143 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPPQ.h" + +int XPPQ::OK() +{ + int v = p.OK(); + v &= p.low() == 1; + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPPQ::seek( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + if (EQ(p[i],item)) return p.index_to_Pix(i); + return 0; +} + +// standard 2-ary heap ops +// pointers are used a lot to avoid thrashing across chunks with plexes + +Pix XPPQ::enq( item) +{ + p.add_high(item); + * pk = &(p.high_element()); + int par = ++count >> 1; + while (par != 0) + { + * ppar = &(p[par]); + if (!(LE(*ppar, item))) + { + *pk = *ppar; + pk = ppar; + par >>= 1; + } + else + break; + } + *pk = item; + return Pix(pk); +} + +void XPPQ::del_front() +{ + if (count == 0) error("empty PQ"); + --count; + * pk = &(p.low_element()); + * ph = &(p.high_element()); + int child = 2; + while (child <= count) + { + * pchild = &(p[child]); + if (child < count) + { + * prchild = &(p[child+1]); + if (!(LE(*pchild, *prchild))) + { + pchild = prchild; + ++child; + } + } + if (!(LE(*ph, *pchild))) + { + *pk = *pchild; + pk = pchild; + child <<= 1; + } + else + break; + } + *pk = *ph; + p.del_high(); +} + + +void XPPQ::del(Pix i) +{ + if (i == 0) error("null Pix"); + --count; + int k = p.Pix_to_index(i); + * pk = &(p[k]); + * ph = &(p.high_element()); + int child = k << 1; + while (child <= count) + { + * pchild = &(p[child]); + if (child < count) + { + * prchild = &(p[child+1]); + if (!(LE(*pchild, *prchild))) + { + pchild = prchild; + ++child; + } + } + if (!(LE(*ph, *pchild))) + { + *pk = *pchild; + pk = pchild; + child <<= 1; + } + else + break; + } + int par = child >> 2; + while (par != 0) + { + * ppar = &(p[par]); + if (!(LE(*ppar, *ph))) + { + *pk = *ppar; + pk = ppar; + par >>= 1; + } + else + break; + } + *pk = *ph; + p.del_high(); +} + + diff --git a/gnu/lib/libg++/g++-include/XPPQ.hP b/gnu/lib/libg++/g++-include/XPPQ.hP new file mode 100644 index 0000000000..af813a2b90 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPPQ.hP @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPPQ_h 1 + +#include ".PQ.h" +#include ".XPlex.h" + +class XPPQ : public PQ +{ +protected: + XPlex p; + +public: + XPPQ(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPPQ(const XPPQ&); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + void del(Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + +inline XPPQ::XPPQ(int chunksize) + : p(1, chunksize) { count = 0; } + +inline XPPQ::XPPQ(const XPPQ& s) : p(s.p) { count = s.count; } + +inline Pix XPPQ::first() +{ + return p.first(); +} + +inline void XPPQ::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPPQ::operator ()(Pix idx) +{ + return p(idx); +} + +inline & XPPQ::front () +{ + return p.low_element(); +} + +inline XPPQ::deq () +{ + x = p.low_element(); + del_front(); + return x; +} + +inline void XPPQ::clear() +{ + count = 0; p.clear(); +} + +inline int XPPQ::contains ( item) +{ + return seek(item) != 0; +} + +inline int XPPQ::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPQueue.ccP b/gnu/lib/libg++/g++-include/XPQueue.ccP new file mode 100644 index 0000000000..77bfd1c7a9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPQueue.h" diff --git a/gnu/lib/libg++/g++-include/XPQueue.hP b/gnu/lib/libg++/g++-include/XPQueue.hP new file mode 100644 index 0000000000..ebae20f3f6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPQueue.hP @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPQueue_h + +#include ".XPlex.h" +#include ".Queue.h" + +class XPQueue : public Queue +{ +protected: + XPlex p; + +public: + XPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPQueue(const XPQueue& q); + ~XPQueue(); + + void operator = (const XPQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline XPQueue::XPQueue(int chunksize) + : p(chunksize) {} +inline XPQueue::XPQueue(const XPQueue& q) : p(q.p) {} + +inline XPQueue::~XPQueue() {} + +inline void XPQueue::enq(item) +{ + p.add_high(item); +} + +inline XPQueue::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & XPQueue::front() +{ + return p.low_element(); +} + + +inline void XPQueue::del_front() +{ + p.del_low(); +} + +inline void XPQueue::operator =(const XPQueue& s) +{ + p.operator = (s.p); +} + +inline int XPQueue::empty() +{ + return p.empty(); +} + +inline int XPQueue::full() +{ + return p.full(); +} + +inline int XPQueue::length() +{ + return p.length(); +} + +inline int XPQueue::OK() +{ + return p.OK(); +} + +inline void XPQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPSet.ccP b/gnu/lib/libg++/g++-include/XPSet.ccP new file mode 100644 index 0000000000..1102790700 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPSet.ccP @@ -0,0 +1,63 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPSet.h" + +int XPSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPSet::seek( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + if (EQ(p[i],item)) return p.index_to_Pix(i); + return 0; +} + +Pix XPSet::add( item) +{ + Pix i = seek(item); + if (i == 0) + { + ++count; + i = p.index_to_Pix(p.add_high(item)); + } + return i; +} + +void XPSet::del( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + return; + } + } +} + diff --git a/gnu/lib/libg++/g++-include/XPSet.hP b/gnu/lib/libg++/g++-include/XPSet.hP new file mode 100644 index 0000000000..9269ec12c8 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPSet.hP @@ -0,0 +1,89 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPSet_h 1 + +#include ".Set.h" +#include ".XPlex.h" + +class XPSet : public Set +{ +protected: + XPlex p; + +public: + XPSet(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPSet(const XPSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); +}; + + +inline XPSet::XPSet(int chunksize) + : p(chunksize) { count = 0; } + +inline XPSet::XPSet(const XPSet& s) : p(s.p) { count = s.count; } + +inline Pix XPSet::first() +{ + return p.first(); +} + +inline void XPSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void XPSet::clear() +{ + count = 0; p.clear(); +} + +inline int XPSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int XPSet::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPStack.ccP b/gnu/lib/libg++/g++-include/XPStack.ccP new file mode 100644 index 0000000000..fe24f0f044 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPStack.h" diff --git a/gnu/lib/libg++/g++-include/XPStack.hP b/gnu/lib/libg++/g++-include/XPStack.hP new file mode 100644 index 0000000000..9d103e530d --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPStack.hP @@ -0,0 +1,115 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPStack_h + +#include ".XPlex.h" +#include ".Stack.h" + +class XPStack : public Stack +{ + XPlex p; + +public: + XPStack(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPStack(const XPStack& s); + ~XPStack(); + + void operator = (const XPStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + + +inline XPStack::XPStack(int chunksize) + : p(chunksize) {} +inline XPStack::XPStack(const XPStack& s) : p(s.p) {} + +inline XPStack::~XPStack() {} + +inline void XPStack::push(item) +{ + p.add_high(item); +} + +inline XPStack::pop() +{ + res = p.high_element(); + p.del_high(); + return res; +} + +inline & XPStack::top() +{ + return p.high_element(); +} + +inline void XPStack::del_top() +{ + p.del_high(); +} + +inline void XPStack::operator =(const XPStack& s) +{ + p.operator = (s.p); +} + +inline int XPStack::empty() +{ + return p.empty(); +} + +inline int XPStack::full() +{ + return p.full(); +} + +inline int XPStack::length() +{ + return p.length(); +} + +inline int XPStack::OK() +{ + return p.OK(); +} + +inline void XPStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/XPlex.ccP b/gnu/lib/libg++/g++-include/XPlex.ccP new file mode 100644 index 0000000000..c91e5035a4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPlex.ccP @@ -0,0 +1,397 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPlex.h" + + +XPlex:: XPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; +} + +XPlex:: XPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize, lo, fnc, fnc)); + hd = ch; + } +} + + +XPlex:: XPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize+lo)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } +} + +void XPlex::make_initial_chunks(int up) +{ + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + set_cache(hd); +} + +XPlex:: XPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + fill(initval); +} + +XPlex::XPlex(const XPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void XPlex::operator= (const XPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void XPlex::cache(int idx) const +{ + const IChunk* tail = tl(); + const IChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) index_error(); + t = (t->next()); + } + while (idx < t->low_index()) + { + if (t == hd) index_error(); + t = (t->prev()); + } + set_cache(t); +} + + +void XPlex::cache(const * p) const +{ + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) index_error(); + } + set_cache(t); +} + +int XPlex::owns(Pix px) const +{ + * p = (*)px; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) { set_cache(t); return 0; } + } + set_cache(t); + return 1; +} + + +* XPlex::dosucc(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + int i = t->index_of(p) + 1; + if (i >= fnc) return 0; + if (i >= t->fence_index()) t = (t->next()); + set_cache(t); + return (t->pointer_to(i)); +} + +* XPlex::dopred(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->prev()); + if (t == old) return 0; + } + int i = t->index_of(p) - 1; + if (i < lo) return 0; + if (i < t->low_index()) t = (t->prev()); + set_cache(t); + return (t->pointer_to(i)); +} + + +int XPlex::add_high(const elem) +{ + IChunk* t = tl(); + if (!t->can_grow_high()) + { + if (t->IChunk::empty() && one_chunk()) + t->clear(fnc); + else + { + * data = new [csize]; + t = (new IChunk(data, fnc, fnc, fnc,fnc+csize)); + t->link_to_prev(tl()); + } + } + *((t->IChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int XPlex::del_high () +{ + if (empty()) empty_error(); + IChunk* t = tl(); + t->IChunk::shrink_high(); + if (t->IChunk::empty() && !one_chunk()) + { + IChunk* pred = t->prev(); + del_chunk(t); + t = pred; + } + set_cache(t); + return --fnc - 1; +} + +int XPlex::add_low (const elem) +{ + IChunk* t = hd; + if (!t->can_grow_low()) + { + if (t->IChunk::empty() && one_chunk()) + t->cleardown(lo); + else + { + * data = new [csize]; + hd = new IChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = hd; + } + } + *((t->IChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + + +int XPlex::del_low () +{ + if (empty()) empty_error(); + IChunk* t = hd; + t->IChunk::shrink_low(); + if (t->IChunk::empty() && !one_chunk()) + { + hd = t->next(); + del_chunk(t); + t = hd; + } + set_cache(t); + return ++lo; +} + +void XPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + IChunk* loch = hd; + IChunk* hich = tl(); + while (l < h) + { + * lptr = loch->pointer_to(l); + * hptr = hich->pointer_to(h); + tmp = *lptr; + *lptr = *hptr; + *hptr = tmp; + if (++l >= loch->fence_index()) loch = loch->next(); + if (--h < hich->low_index()) hich = hich->prev(); + } +} + +void XPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void XPlex::fill(const x, int l, int hi) +{ + for (int i = l; i <= hi; ++i) (*this)[i] = x; +} + + +void XPlex::clear() +{ + if (fnc != lo) + { + IChunk* t = tl(); + while (t != hd) + { + IChunk* prv = t->prev(); + del_chunk(t); + t = prv; + } + t->IChunk::clear(lo); + set_cache(t); + fnc = lo; + } +} + + +int XPlex::OK () const +{ + int v = hd != 0 && ch != 0; // at least one chunk + + v &= fnc == tl()->fence_index();// last chunk fence == plex fence + v &= lo == ((hd))->IChunk::low_index(); // first lo == plex lo + +// loop for others: + int found_ch = 0; // to make sure ch is in list; + const IChunk* t = (hd); + for (;;) + { + if (t == ch) ++found_ch; + v &= t->IChunk::OK(); // each chunk is OK + if (t == tl()) + break; + else // and has indices contiguous to succ + { + v &= t->top_index() == t->next()->base_index(); + if (t != hd) // internal chunks full + { + v &= !t->empty(); + v &= !t->can_grow_low(); + v &= !t->can_grow_high(); + } + t = t->next(); + } + } + v &= found_ch == 1; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/XPlex.hP b/gnu/lib/libg++/g++-include/XPlex.hP new file mode 100644 index 0000000000..41f100091b --- /dev/null +++ b/gnu/lib/libg++/g++-include/XPlex.hP @@ -0,0 +1,238 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _XPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPlex_h 1 + +#include ".Plex.h" + +class XPlex: public Plex +{ + IChunk* ch; // cached chunk + + void make_initial_chunks(int up = 1); + + void cache(int idx) const; + void cache(const * p) const; + + * dopred(const * p) const; + * dosucc(const * p) const; + + void set_cache(const IChunk* t) const; // logically, + // not physically const +public: + XPlex(); // set low = 0; + // fence = 0; + // csize = default + + XPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + XPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + XPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + XPlex(const XPlex&); + + void operator= (const XPlex&); + +// virtuals + + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int OK () const; + +}; + + +inline void XPlex::prev(int& idx) const +{ + --idx; +} + +inline void XPlex::next(int& idx) const +{ + ++idx; +} + +inline int XPlex::full () const +{ + return 0; +} + +inline int XPlex::can_add_high() const +{ + return 1; +} + +inline int XPlex::can_add_low() const +{ + return 1; +} + +inline int XPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int XPlex::low() const +{ + return lo; +} + +inline int XPlex::high() const +{ + return fnc - 1; +} + +inline & XPlex:: operator [] (int idx) +{ + if (!ch->actual_index(idx)) cache(idx); + return *(ch->pointer_to(idx)); +} + +inline const & XPlex:: operator [] (int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return *((const *)(ch->pointer_to(idx))); +} + +inline & XPlex::low_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline const & XPlex::low_element () const +{ + if (empty()) index_error(); + return *((const *)(hd->pointer_to(lo))); +} + +inline & XPlex::high_element () +{ + if (empty()) index_error(); + return *(tl()->pointer_to(fnc - 1)); +} + +inline const & XPlex::high_element () const +{ + if (empty()) index_error(); + return *((const *)(tl()->pointer_to(fnc - 1))); +} + +inline int XPlex::Pix_to_index(Pix px) const +{ + * p = (*)px; + if (!ch->actual_pointer(p)) cache(p); + return ch->index_of(p); +} + +inline Pix XPlex::index_to_Pix(int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return (Pix)(ch->pointer_to(idx)); +} + +inline Pix XPlex::first() const +{ + return Pix(hd->IChunk::first_pointer()); +} + +inline Pix XPlex::last() const +{ + return Pix(tl()->IChunk::last_pointer()); +} + +inline void XPlex::prev(Pix& p) const +{ + Pix q = Pix(ch->IChunk::pred((*) p)); + p = (q == 0)? Pix(dopred((const *) p)) : q; +} + +inline void XPlex::next(Pix& p) const +{ + Pix q = Pix(ch->IChunk::succ((*) p)); + p = (q == 0)? Pix(dosucc((const *)p)) : q; +} + +inline & XPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline const & XPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline void XPlex::set_cache(const IChunk* t) const +{ + ((XPlex*)(this))->ch = (IChunk*)t; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/defs.hP b/gnu/lib/libg++/g++-include/defs.hP new file mode 100644 index 0000000000..054f6a65c3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/defs.hP @@ -0,0 +1,57 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _defs_h +#define _defs_h 1 + + +// equality operator +#ifndef EQ +#define EQ(a, b) ((a) == (b)) +#endif + +// less-than-or-equal +#ifndef LE +#define LE(a, b) ((a) <= (b)) +#endif + +// comparison : less-than -> < 0; equal -> 0; greater-than -> > 0 +#ifndef CMP +#define CMP(a, b) ( ((a) <= (b))? (((a) == (b))? 0 : -1) : 1 ) +#endif + +// hash function +#ifndef HASH +extern unsigned int hash(); +#define HASH(x) hash(x) +#endif + +// initial capacity for structures requiring one + +#ifndef DEFAULT_INITIAL_CAPACITY +#define DEFAULT_INITIAL_CAPACITY 100 +#endif + +// HASHTABLE_TOO_CROWDED(COUNT, SIZE) is true iff a hash table with COUNT +// elements and SIZE slots is too full, and should be resized. +// This is so if available space is less than 1/8. + +#define HASHTABLE_TOO_CROWDED(COUNT, SIZE) ((SIZE) - ((SIZE) >> 3) <= (COUNT)) + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVLMap.ccP b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP new file mode 100644 index 0000000000..a9be60f066 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP @@ -0,0 +1,614 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..AVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +AVLNode* AVLMap::leftmost() +{ + AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +AVLNode* AVLMap::rightmost() +{ + AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +AVLNode* AVLMap::succ(AVLNode* t) +{ + AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +AVLNode* AVLMap::pred(AVLNode* t) +{ + AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix AVLMap::seek( key) +{ + AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + + +void AVLMap:: _add(AVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +& AVLMap::operator [] ( item) +{ + if (root == 0) + { + ++count; + root = new AVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return _found_node->cont; + } +} + + +void AVLMap::_del(AVLNode* par, AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + AVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void AVLMap::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void AVLMap::_kill(AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +AVLMap::AVLMap(AVLMap& b) :Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int AVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + AVLNode* trail = leftmost(); + AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVLMap.hP b/gnu/lib/libg++/g++-include/gen/AVLMap.hP new file mode 100644 index 0000000000..119ee82caa --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLMap.hP @@ -0,0 +1,141 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVLMap_h 1 + +#include "..Map.h" + +struct AVLNode +{ + AVLNode* lt; + AVLNode* rt; + item; + cont; + char stat; + AVLNode( h, c, + AVLNode* l=0, AVLNode* r=0); + ~AVLNode(); +}; + +inline AVLNode::AVLNode( h, c, + AVLNode* l, AVLNode* r) + :item(h), cont(c), lt(l), rt(r), stat(0) {} + +inline AVLNode::~AVLNode() {} + +typedef AVLNode* AVLNodePtr; + + +class AVLMap : public Map +{ +protected: + AVLNode* root; + + AVLNode* leftmost(); + AVLNode* rightmost(); + AVLNode* pred(AVLNode* t); + AVLNode* succ(AVLNode* t); + void _kill(AVLNode* t); + void _add(AVLNode*& t); + void _del(AVLNode* p, AVLNode*& t); + +public: + AVLMap( dflt); + AVLMap(AVLMap& a); + ~AVLMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline AVLMap::~AVLMap() +{ + _kill(root); +} + +inline AVLMap::AVLMap( dflt) :Map(dflt) +{ + root = 0; +} + +inline Pix AVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix AVLMap::last() +{ + return Pix(rightmost()); +} + +inline void AVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((AVLNode*)i)); +} + +inline void AVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((AVLNode*)i)); +} + +inline & AVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->item; +} + +inline & AVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->cont; +} + +inline void AVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int AVLMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVLSet.ccP b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP new file mode 100644 index 0000000000..b170734e54 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP @@ -0,0 +1,892 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".AVLSet.h" +#include + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +AVLNode* AVLSet::leftmost() +{ + AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +AVLNode* AVLSet::rightmost() +{ + AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +AVLNode* AVLSet::succ(AVLNode* t) +{ + AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +AVLNode* AVLSet::pred(AVLNode* t) +{ + AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix AVLSet::seek( key) +{ + AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + +static AVLNode** _hold_nodes; // used for rebuilding trees +static int _max_hold_index; // # elements-1 in _hold_nodes + + +void AVLSet:: _add(AVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new AVLNode(*_target_item); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +Pix AVLSet::add( item) +{ + if (root == 0) + { + ++count; + root = new AVLNode(item); + set_rthread(root, 1); + set_lthread(root, 1); + return Pix(root); + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return Pix(_found_node); + } +} + + +void AVLSet::_del(AVLNode* par, AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + AVLNode* p = pred(t); + t->item = p->item; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void AVLSet::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +// build an ordered array of pointers to tree nodes back into a tree +// we know that at least one element exists + +static AVLNode* _do_treeify(int lo, int hi, int& h) +{ + int lh, rh; + int mid = (lo + hi) / 2; + AVLNode* t = _hold_nodes[mid]; + if (lo > mid - 1) + { + set_lthread(t, 1); + if (mid == 0) + t->lt = 0; + else + t->lt = _hold_nodes[mid-1]; + lh = 0; + } + else + { + set_lthread(t, 0); + t->lt = _do_treeify(lo, mid-1, lh); + } + if (hi < mid + 1) + { + set_rthread(t, 1); + if (mid == _max_hold_index) + t->rt = 0; + else + t->rt = _hold_nodes[mid+1]; + rh = 0; + } + else + { + set_rthread(t, 0); + t->rt = _do_treeify(mid+1, hi, rh); + } + if (lh == rh) + { + set_bf(t, AVLBALANCED); + h = lh + 1; + } + else if (lh == rh - 1) + { + set_bf(t, AVLRIGHTHEAVY); + h = rh + 1; + } + else if (rh == lh - 1) + { + set_bf(t, AVLLEFTHEAVY); + h = lh + 1; + } + else // can't happen + abort(); + + return t; +} + +static AVLNode* _treeify(int n) +{ + AVLNode* t; + if (n == 0) + t = 0; + else + { + int b; + _max_hold_index = n-1; + t = _do_treeify(0, _max_hold_index, b); + } + delete _hold_nodes; + return t; +} + + +void AVLSet::_kill(AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +AVLSet::AVLSet(AVLSet& b) +{ + if ((count = b.count) == 0) + { + root = 0; + } + else + { + _hold_nodes = new AVLNodePtr [count]; + AVLNode* t = b.leftmost(); + int i = 0; + while (t != 0) + { + _hold_nodes[i++] = new AVLNode(t->item); + t = b.succ(t); + } + root = _treeify(count); + } +} + + +int AVLSet::operator == (AVLSet& y) +{ + if (count != y.count) + return 0; + else + { + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!(EQ(t->item, u->item))) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int AVLSet::operator <= (AVLSet& y) +{ + if (count > y.count) + return 0; + else + { + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + +void AVLSet::operator |=(AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = count + y.count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + { + while (u != 0) + { + _hold_nodes[k++] = new AVLNode(u->item); + u = y.succ(u); + } + break; + } + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + { + _hold_nodes[k++] = new AVLNode(u->item); + u = y.succ(u); + } + } + root = _treeify(k); + count = k; +} + +void AVLSet::operator &= (AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = (count < y.count)? count : y.count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + if (u == 0) + { + while (t != 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + + +void AVLSet::operator -=(AVLSet& y) +{ + AVLNode* t = leftmost(); + AVLNode* u = y.leftmost(); + int rsize = count; + _hold_nodes = new AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + AVLNode* tmp = succ(t); + delete t; + t = tmp; + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + +int AVLSet::owns(Pix i) +{ + if (i == 0) return 0; + for (AVLNode* t = leftmost(); t != 0; t = succ(t)) + if (Pix(t) == i) return 1; + return 0; +} + +int AVLSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + AVLNode* trail = leftmost(); + AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVLSet.hP b/gnu/lib/libg++/g++-include/gen/AVLSet.hP new file mode 100644 index 0000000000..16ad1d1946 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVL_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVL_h 1 + +#include ".Set.h" + +struct AVLNode +{ + AVLNode* lt; + AVLNode* rt; + item; + char stat; + AVLNode( h, AVLNode* l=0, AVLNode* r=0); + ~AVLNode(); +}; + +inline AVLNode::AVLNode( h, AVLNode* l, AVLNode* r) +:item(h), lt(l), rt(r), stat(0) {} + +inline AVLNode::~AVLNode() {} + +typedef AVLNode* AVLNodePtr; + + +class AVLSet : public Set +{ +protected: + AVLNode* root; + + AVLSet(AVLNode* p, int l); + + AVLNode* leftmost(); + AVLNode* rightmost(); + AVLNode* pred(AVLNode* t); + AVLNode* succ(AVLNode* t); + void _kill(AVLNode* t); + void _add(AVLNode*& t); + void _del(AVLNode* p, AVLNode*& t); + +public: + AVLSet(); + AVLSet(AVLSet& a); + ~AVLSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + void operator |= (AVLSet& b); + void operator -= (AVLSet& b); + void operator &= (AVLSet& b); + + int operator == (AVLSet& b); + int operator != (AVLSet& b); + int operator <= (AVLSet& b); + + int OK(); +}; + +inline AVLSet::~AVLSet() +{ + _kill(root); +} + +inline AVLSet::AVLSet() +{ + root = 0; + count = 0; +} + +inline AVLSet::AVLSet(AVLNode* p, int l) +{ + root = p; + count = l; +} + +inline int AVLSet::operator != (AVLSet& b) +{ + return ! ((*this) == b); +} + +inline Pix AVLSet::first() +{ + return Pix(leftmost()); +} + +inline Pix AVLSet::last() +{ + return Pix(rightmost()); +} + +inline void AVLSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((AVLNode*)i)); +} + +inline void AVLSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((AVLNode*)i)); +} + +inline & AVLSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((AVLNode*)i)->item; +} + +inline void AVLSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int AVLSet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVec.ccP b/gnu/lib/libg++/g++-include/gen/AVec.ccP new file mode 100644 index 0000000000..bc671bf8e1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVec.ccP @@ -0,0 +1,397 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".AVec.h" + +/* + The following brought to you by the department of redundancy department +*/ + +AVec& AVec::operator = (AVec& v) +{ + if (len != 0 && len != v.capacity()) + error("nonconformant vectors."); + if (len == 0) + s = new [len = v.capacity()]; + if (s != v.vec()) + { + for (int i = 0; i < len; ++i) + s[i] = v.vec()[i]; + } + return *this; +} + +AVec& AVec::operator = ( f) +{ + for (int i = 0; i < len; ++i) s[i] = f; + return *this; +} + + +AVec concat(AVec & a, AVec & b) +{ + int newl = a.capacity() + b.capacity(); + * news = new [newl]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++; + top = &(b.vec()[b.capacity()]); + t = b.vec(); + while (t < top) *p++ = *t++; + return AVec(newl, news); +} + + +AVec combine(Combiner f, AVec& a, AVec& b) +{ + int newl = (a.capacity() < b.capacity())? a.capacity() : b.capacity(); + * news = new [newl]; + * p = news; + * top = &(a.vec()[newl]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = (*f)(*t++, *u++); + return AVec(newl, news); +} + +AVec reverse(AVec& a) +{ + * news = new [a.capacity()]; + if (a.capacity() != 0) + { + * lo = news; + * hi = &(news[a.capacity() - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } + return AVec(a.capacity(), news); +} + +AVec map(Mapper f, AVec& a) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while(t < top) *p++ = (*f)(*t++); + return AVec(a.capacity(), news); +} + +AVec AVec::at(int from, int n) +{ + int to; + if (n < 0) + { + n = len - from; + to = len - 1; + } + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * news = new [n]; + * p = news; + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *p++ = *t++; + return AVec(n, news); +} + +AVec merge(AVec & a, AVec & b, Comparator f) +{ + int newl = a.capacity() + b.capacity(); + * news = new [newl]; + * p = news; + * topa = &(a.vec()[a.capacity()]); + * as = a.vec(); + * topb = &(b.vec()[b.capacity()]); + * bs = b.vec(); + + for (;;) + { + if (as >= topa) + { + while (bs < topb) *p++ = *bs++; + break; + } + else if (bs >= topb) + { + while (as < topa) *p++ = *as++; + break; + } + else if ((*f)(*as, *bs) <= 0) + *p++ = *as++; + else + *p++ = *bs++; + } + return AVec(newl, news); +} + +AVec operator + (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ + *u++; + return AVec(a.capacity(), news); +} + +AVec operator - (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ - *u++; + return AVec(a.capacity(), news); +} + +AVec product (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ * *u++; + return AVec(a.capacity(), news); +} + +AVec quotient(AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + while (t < top) *p++ = *t++ / *u++; + return AVec(a.capacity(), news); +} + +AVec operator + (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ + b; + return AVec(a.capacity(), news); +} + +AVec operator - (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ - b; + return AVec(a.capacity(), news); +} + +AVec operator * (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ * b; + return AVec(a.capacity(), news); +} + +AVec operator / (AVec& a, b) +{ + * news = new [a.capacity()]; + * p = news; + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + while (t < top) *p++ = *t++ / b; + return AVec(a.capacity(), news); +} + +AVec AVec::operator - () +{ + * news = new [len]; + * p = news; + * top = &(s[len]); + * t = s; + while (t < top) *p++ = -(*t++); + return AVec(len, news); +} + +AVec& AVec::operator += (AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ += *u++; + return *this; +} + +AVec& AVec::operator -= (AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ -= *u++; + return *this; +} + +AVec& AVec::product(AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ *= *u++; + return *this; +} + +AVec& AVec::quotient(AVec& b) +{ + check_len(b.capacity()); + * u = b.vec(); + * top = &(s[len]); + * t = s; + while (t < top) *t++ /= *u++; + return *this; +} + +AVec& AVec::operator += ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ += b; + return *this; +} + +AVec& AVec::operator -= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ -= b; + return *this; +} + +AVec& AVec::operator *= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ *= b; + return *this; +} + +AVec& AVec::operator /= ( b) +{ + * top = &(s[len]); + * t = s; + while (t < top) *t++ /= b; + return *this; +} + + AVec::max() +{ + if (len == 0) + return 0; + * top = &(s[len]); + * t = s; + res = *t++; + for (; t < top; ++t) if (*t > res) res = *t; + return res; +} + +int AVec::max_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] > s[ind]) + ind = i; + return ind; +} + + AVec::min() +{ + if (len == 0) + return 0; + * top = &(s[len]); + * t = s; + res = *t++; + for (; t < top; ++t) if (*t < res) res = *t; + return res; +} + +int AVec::min_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] < s[ind]) + ind = i; + return ind; +} + + AVec::sum() +{ + res = 0; + * top = &(s[len]); + * t = s; + while (t < top) res += *t++; + return res; +} + + + AVec::sumsq() +{ + res = 0; + * top = &(s[len]); + * t = s; + for (; t < top; ++t) res += *t * *t; + return res; +} + + operator * (AVec& a, AVec& b) +{ + a.check_len(b.capacity()); + * top = &(a.vec()[a.capacity()]); + * t = a.vec(); + * u = b.vec(); + res = 0; + while (t < top) res += *t++ * *u++; + return res; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVec.hP b/gnu/lib/libg++/g++-include/gen/AVec.hP new file mode 100644 index 0000000000..cd9a9c3fe5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVec.hP @@ -0,0 +1,113 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _AVec_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _AVec_h 1 + +#include ".Vec.h" + +class AVec : public Vec +{ +protected: + void check_len(int l); + * vec(); + AVec(int l, * d); + public: + AVec (); + AVec (int l); + AVec (int l, fill_value); + AVec (AVec&); + ~AVec (); + + AVec& operator = (AVec& a); + AVec& operator = ( fill_value); + +// vector by scalar -> vector operations + + friend AVec operator + (AVec& a, b); + friend AVec operator - (AVec& a, b); + friend AVec operator * (AVec& a, b); + friend AVec operator / (AVec& a, b); + + AVec& operator += ( b); + AVec& operator -= ( b); + AVec& operator *= ( b); + AVec& operator /= ( b); + +// vector by vector -> vector operations + + friend AVec operator + (AVec& a, AVec& b); + friend AVec operator - (AVec& a, AVec& b); + AVec& operator += (AVec& b); + AVec& operator -= (AVec& b); + + AVec operator - (); + + friend AVec product(AVec& a, AVec& b); + AVec& product(AVec& b); + friend AVec quotient(AVec& a, AVec& b); + AVec& quotient(AVec& b); + +// vector -> scalar operations + + friend operator * (AVec& a, AVec& b); + + sum(); + min(); + max(); + sumsq(); + +// indexing + + int min_index(); + int max_index(); + +// redundant but necesssary + friend AVec concat(AVec& a, AVec& b); + friend AVec map(Mapper f, AVec& a); + friend AVec merge(AVec& a, AVec& b, Comparator f); + friend AVec combine(Combiner f, AVec& a, AVec& b); + friend AVec reverse(AVec& a); + AVec at(int from = 0, int n = -1); +}; + +inline AVec::AVec() {} +inline AVec::AVec(int l) :Vec(l) {} +inline AVec::AVec(int l, fill_value) : Vec (l, fill_value) {} +inline AVec::AVec(AVec& v) :Vec(v) {} +inline AVec::AVec(int l, * d) :Vec(l, d) {} +inline AVec::~AVec() {} + + +inline * AVec::vec() +{ + return s; +} + + +inline void AVec::check_len(int l) +{ + if (l != len) + error("nonconformant vectors."); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/BSTSet.ccP b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP new file mode 100644 index 0000000000..6a69d8f45b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP @@ -0,0 +1,378 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".BSTSet.h" + + +/* + traversal primitives +*/ + + +BSTNode* BSTSet::leftmost() +{ + BSTNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +BSTNode* BSTSet::rightmost() +{ + BSTNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +BSTNode* BSTSet::succ(BSTNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +BSTNode* BSTSet::pred(BSTNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix BSTSet::seek( key) +{ + BSTNode* t = root; + for (;;) + { + if (t == 0) + return 0; + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + else if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +Pix BSTSet::add( item) +{ + if (root == 0) + { + ++count; + root = new BSTNode(item); + return Pix(root); + } + + BSTNode* t = root; + BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + { + ++count; + t = new BSTNode(item); + if (comp > 0) + p->lt = t; + else + p->rt = t; + t->par = p; + return Pix(t); + } + p = t; + comp = CMP(t->item, item); + if (comp == 0) + return Pix(t); + else if (comp > 0) + t = t->lt; + else + t = t->rt; + } +} + + +void BSTSet::del( key) +{ + BSTNode* t = root; + BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + return; + comp = CMP(key, t->item); + if (comp == 0) + { + --count; + BSTNode* repl; + if (t->lt == 0) + repl = t->rt; + else if (t->rt == 0) + repl = t->lt; + else + { + BSTNode* prepl = t; + repl = t->lt; + while (repl->rt != 0) + { + prepl = repl; + repl = repl->rt; + } + if (prepl != t) + { + prepl->rt = repl->lt; + if (prepl->rt != 0) prepl->rt->par = prepl; + repl->lt = t->lt; + if (repl->lt != 0) repl->lt->par = repl; + } + repl->rt = t->rt; + if (repl->rt != 0) repl->rt->par = repl; + } + if (t == root) + { + root = repl; + if (repl != 0) repl->par = 0; + } + else + { + if (t == p->lt) + p->lt = repl; + else + p->rt = repl; + if (repl != 0) repl->par = p; + } + delete t; + return; + } + p = t; + if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +void BSTSet::_kill(BSTNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + +BSTNode* BSTSet::_copy(BSTNode* t) +{ + if (t == 0) + return 0; + else + { + BSTNode* u = new BSTNode(t->item, _copy(t->lt), _copy(t->rt)); + if (u->lt != 0) u->lt->par = u; + if (u->rt != 0) u->rt->par = u; + return u; + } +} + + +int BSTSet::operator == (BSTSet& y) +{ + if (count != y.count) + return 0; + else + { + BSTNode* t = leftmost(); + BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int BSTSet::operator <= (BSTSet& y) +{ + if (count > y.count) + return 0; + else + { + BSTNode* t = leftmost(); + BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +// linear-time, zero space overhead binary tree rebalancing from +// Stout & Warren, ``Tree rebalancing in linear space and time'' +// CACM, Sept, 1986, p902. + + +void BSTSet::balance() +{ + if (count <= 2) return; // don't bother -- + // also we assume non-null root, below + + // make re-attaching the root easy via trickery + + struct _fake_node { _fake_node *lt, *rt, *par; } fake_root; + + fake_root.rt = (_fake_node*)root; + fake_root.par = 0; + BSTNode* pseudo_root = (BSTNode*)&fake_root; + + // phase 1: tree-to-vine + + BSTNode* vine_tail = pseudo_root; + BSTNode* remainder = root; + + while (remainder != 0) + { + if (remainder->lt == 0) + { + vine_tail = remainder; + remainder = remainder->rt; + } + else + { + BSTNode* tmp = remainder->lt; + remainder->lt = tmp->rt; + if (remainder->lt != 0) remainder->lt->par = remainder; + tmp->rt = remainder; + remainder->par = tmp; + vine_tail->rt = remainder = tmp; + } + } + + // phase 2: vine-to-tree + + // Uses the slightly simpler version adapted from + // Day ``Balancing a binary tree'' Computer Journal, Nov. 1976, + // since it's not generally important whether the `stray' leaves are + // on the left or on the right. + + unsigned int spines = count - 1; + while (spines > 1) + { + int compressions = spines >> 1; // compress every other node + spines -= compressions + 1; // halve for next time + + BSTNode* scanner = pseudo_root; + while (compressions-- > 0) + { + BSTNode* child = scanner->rt; + BSTNode* grandchild = child->rt; + scanner->rt = grandchild; + grandchild->par = scanner; + child->rt = grandchild->lt; + if (child->rt != 0) child->rt->par = child; + grandchild->lt = child; + child->par = grandchild; + scanner = grandchild; + } + } + + root = pseudo_root->rt; + root->par = 0; +} + + +int BSTSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + BSTNode* trail = leftmost(); + BSTNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/BSTSet.hP b/gnu/lib/libg++/g++-include/gen/BSTSet.hP new file mode 100644 index 0000000000..82f2069c0f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/BSTSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _BSTSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _BSTSet_h 1 + +#include ".Set.h" + +#ifndef _BSTNode +#define _BSTNode 1 + +struct BSTNode +{ + BSTNode* lt; + BSTNode* rt; + BSTNode* par; + item; + BSTNode( h, BSTNode* l=0, BSTNode* r=0, + BSTNode* p = 0); + ~BSTNode(); +}; + +inline BSTNode::BSTNode( h, BSTNode* l, BSTNode* r, + BSTNode* p) +:item(h), lt(l), rt(r), par(p) {} + +inline BSTNode::~BSTNode() {} + +typedef BSTNode* BSTNodePtr; + +#endif + +class BSTSet : public Set +{ +protected: + BSTNode* root; + + BSTNode* leftmost(); + BSTNode* rightmost(); + BSTNode* pred(BSTNode* t); + BSTNode* succ(BSTNode* t); + void _kill(BSTNode* t); + BSTNode* _copy(BSTNode* t); + +public: + BSTSet(); + BSTSet(BSTSet& a); + ~BSTSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + int operator == (BSTSet& b); + int operator != (BSTSet& b); + int operator <= (BSTSet& b); + + void balance(); + int OK(); +}; + +inline BSTSet::~BSTSet() +{ + _kill(root); +} + +inline BSTSet::BSTSet() +{ + root = 0; + count = 0; +} + + +inline BSTSet::BSTSet(BSTSet& a) +{ + count = a.count; + root = _copy(a.root); +} + +inline int BSTSet::operator != (BSTSet& b) +{ + return ! (*this == b); +} + +inline Pix BSTSet::first() +{ + return Pix(leftmost()); +} + +inline Pix BSTSet::last() +{ + return Pix(rightmost()); +} + +inline void BSTSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((BSTNode*)i)); +} + +inline void BSTSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((BSTNode*)i)); +} + +inline & BSTSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((BSTNode*)i)->item; +} + +inline void BSTSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int BSTSet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Bag.ccP b/gnu/lib/libg++/g++-include/gen/Bag.ccP new file mode 100644 index 0000000000..836d0d6656 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Bag.ccP @@ -0,0 +1,74 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".Bag.h" + +// error handling + +void Bag::error(const char* msg) +{ + (*lib_error_handler)("Bag", msg); +} + + +Pix Bag::seek( item, Pix i) +{ + if (i == 0) + i = first(); + else + next(i); + for (;i != 0 && (!(EQ((*this)(i), item))); next(i)); + return i; +} + +int Bag::owns(Pix p) +{ + if (p == 0) return 0; + for (Pix i = first(); i != 0; next(i)) if (i == p) return 1; + return 0; +} + +void Bag::remove( item) +{ + int i = nof(item); + while (i-- > 0) del(item); +} + + +int Bag::nof( item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (EQ((*this)(p), item)) ++n; + return n; +} + +void Bag::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + + diff --git a/gnu/lib/libg++/g++-include/gen/Bag.hP b/gnu/lib/libg++/g++-include/gen/Bag.hP new file mode 100644 index 0000000000..4b9a87a909 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Bag.hP @@ -0,0 +1,79 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Bag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Bag_h 1 + +#include +#include ".defs.h" + +class Bag +{ +protected: + int count; + +public: + virtual ~Bag(); + + int length(); // current number of items + int empty(); + + virtual Pix add( item) = 0; // add item; return Pix + + virtual void del( item) = 0; // delete 1 occurrence of item +#undef remove + virtual void remove( item); // delete all occurrences + virtual void clear(); // delete all items + + virtual int contains( item); // is item in Bag? + virtual int nof( item); // how many in Bag? + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + + virtual & operator () (Pix i) = 0; // access item at i + + virtual Pix seek( item, Pix from=0); // Pix of next occurrence + virtual int owns(Pix i); // is i a valid Pix ? + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline Bag::~Bag() {} + +inline int Bag::length() +{ + return count; +} + +inline int Bag::empty() +{ + return count == 0; +} + +inline int Bag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHBag.ccP b/gnu/lib/libg++/g++-include/gen/CHBag.ccP new file mode 100644 index 0000000000..16649ac22f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHBag.ccP @@ -0,0 +1,209 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHBag.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHBag::CHBag(unsigned int sz) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHBag::CHBag(CHBag& a) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix CHBag::seek( key, Pix i) +{ + CHNode* p = (CHNode*)i; + if (p == 0 || !EQ(p->hd, key)) + { + unsigned int h = HASH(key) % size; + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + } + else + { + for (p = p->tl; goodCHptr(p); p = p->tl) + if (EQ(p->hd, key)) + return Pix(p); + } + return 0; +} + +int CHBag::nof( key) +{ + int n = 0; + unsigned int h = HASH(key) % size; + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) ++n; + return n; +} + + +Pix CHBag::add( item) +{ + unsigned int h = HASH(item) % size; + CHNode* t = new CHNode(item); + t->tl = tab[h]; + tab[h] = t; + ++count; + return Pix(t); +} + +void CHBag::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + +void CHBag::remove( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + --count; + if (trail == t) + { + tab[h] = t->tl; + delete t; + t = trail = tab[h]; + } + else + { + trail->tl = t->tl; + delete t; + t = trail->tl; + } + } + else + { + trail = t; + t = t->tl; + } + } +} + + +void CHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHBag::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHBag::next(Pix& p) +{ + if (p == 0) return; + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int CHBag::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHBag.hP b/gnu/lib/libg++/g++-include/gen/CHBag.hP new file mode 100644 index 0000000000..f6ca10b3b9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHBag.hP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHBag_h 1 + +#include ".Bag.h" + + +#include ".CHNode.h" + +class CHBag : public Bag +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + CHBag(CHBag& a); + ~CHBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline CHBag::~CHBag() +{ + clear(); + delete tab; +} + +inline int CHBag::contains( key) +{ + return seek(key) != 0; +} + +inline & CHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((CHNode*)i)->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHMap.ccP b/gnu/lib/libg++/g++-include/gen/CHMap.ccP new file mode 100644 index 0000000000..1bd76db5fc --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHMap.ccP @@ -0,0 +1,166 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "..CHMap.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHMap::CHMap( dflt, unsigned int sz) + :Map(dflt) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHMap::CHMap(CHMap& a) :Map(a.def) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +Pix CHMap::seek( key) +{ + unsigned int h = HASH(key) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +& CHMap::operator []( item) +{ + unsigned int h = HASH(item) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(item, t->hd)) + return t->cont; + + t = new CHNode(item, def, tab[h]); + tab[h] = t; + ++count; + return t->cont; +} + + +void CHMap::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void CHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHMap::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHMap::next(Pix& p) +{ + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + + +int CHMap::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHMap.hP b/gnu/lib/libg++/g++-include/gen/CHMap.hP new file mode 100644 index 0000000000..95441a3544 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHMap.hP @@ -0,0 +1,104 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHMap_h 1 + +#include "..Map.h" + +#ifndef _CHNode_h +#define _CHNode_h 1 + +struct CHNode +{ + CHNode* tl; + hd; + cont; + CHNode(); + CHNode( h, c, CHNode* t = 0); + ~CHNode(); +}; + +inline CHNode::CHNode() {} + +inline CHNode::CHNode( h, c, CHNode* t) + : hd(h), cont(c), tl(t) {} + +inline CHNode::~CHNode() {} + +typedef CHNode* CHNodePtr; + +#endif + + +class CHMap : public Map +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHMap( dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + CHMap(CHMap& a); + ~CHMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + int OK(); +}; + + +inline CHMap::~CHMap() +{ + clear(); + delete tab; +} + +inline int CHMap::contains( key) +{ + return seek(key) != 0; +} + +inline & CHMap::key(Pix p) +{ + if (p == 0) error("null Pix"); + return ((CHNode*)p)->hd; +} + +inline & CHMap::contents(Pix p) +{ + if (p == 0) error("null Pix"); + return ((CHNode*)p)->cont; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHNode.ccP b/gnu/lib/libg++/g++-include/gen/CHNode.ccP new file mode 100644 index 0000000000..e16725fd74 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHNode.h" diff --git a/gnu/lib/libg++/g++-include/gen/CHNode.hP b/gnu/lib/libg++/g++-include/gen/CHNode.hP new file mode 100644 index 0000000000..84e67d069b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHNode.hP @@ -0,0 +1,43 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _CHNode_h +#define _CHNode_h 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include ".defs.h" + +struct CHNode +{ + CHNode* tl; + hd; + CHNode(); + CHNode( h, CHNode* t = 0); + ~CHNode(); +}; + +inline CHNode::CHNode() {} + +inline CHNode::CHNode( h, CHNode* t) :hd(h), tl(t) {} + +inline CHNode::~CHNode() {} + +typedef CHNode* CHNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHSet.ccP b/gnu/lib/libg++/g++-include/gen/CHSet.ccP new file mode 100644 index 0000000000..330506cb19 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHSet.ccP @@ -0,0 +1,271 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".CHSet.h" + +// A CHSet is implemented as an array (tab) of buckets, each of which +// contains a pointer to a list of CHNodes. Each node contains a +// pointer to the next node in the list, and a pointer to the . +// The end of the list is marked by a next node pointer which is odd +// when considered as an integer (least significant bit = 1). The +// assumption is that CHNodes will all begin on even addresses. If +// the odd pointer is right-shifted by one bit, it becomes the index +// within the tab array of the next bucket (that is, bucket i has +// next bucket pointer 2*(i+1)+1). + +// The bucket pointers are initialized by the constructor and +// used to support the next(Pix&) method. + +// This implementation is not portable to machines with different +// pointer and integer sizes, or on which CHNodes might be aligned on +// odd byte boundaries, but allows the same pointer to be used for +// chaining within a bucket and to the next bucket. + + +static inline int goodCHptr(CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline CHNode* index_to_CHptr(int i) +{ + return (CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +CHSet::CHSet(unsigned int sz) +{ + tab = (CHNode**)(new CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +CHSet::CHSet(CHSet& a) +{ + tab = (CHNode**)(new CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix CHSet::seek( key) +{ + unsigned int h = HASH(key) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +Pix CHSet::add( item) +{ + unsigned int h = HASH(item) % size; + + for (CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (EQ(item, t->hd)) + return Pix(t); + + ++count; + t = new CHNode(item, tab[h]); + tab[h] = t; + return Pix(t); +} + + +void CHSet::del( key) +{ + unsigned int h = HASH(key) % size; + + CHNode* t = tab[h]; + CHNode* trail = t; + while (goodCHptr(t)) + { + if (EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void CHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix CHSet::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void CHSet::next(Pix& p) +{ + if (p == 0) return; + CHNode* t = ((CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int CHSet::operator == (CHSet& b) +{ + if (count != b.count) + return 0; + else + { + CHNode* p; + for (unsigned int i = 0; i < size; ++i) + for (p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + for (i = 0; i < b.size; ++i) + for (p = b.tab[i]; goodCHptr(p); p = p->tl) + if (seek(p->hd) == 0) + return 0; + return 1; + } +} + +int CHSet::operator <= (CHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + return 1; + } +} + +void CHSet::operator |= (CHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + for (CHNode* p = b.tab[i]; goodCHptr(p); p = p->tl) + add(p->hd); +} + +void CHSet::operator &= (CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* t = tab[i]; + CHNode* trail = t; + while (goodCHptr(t)) + { + CHNode* nxt = t->tl; + if (b.seek(t->hd) == 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +void CHSet::operator -= (CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + CHNode* t = tab[i]; + CHNode* trail = t; + while (goodCHptr(t)) + { + CHNode* nxt = t->tl; + if (b.seek(t->hd) != 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +int CHSet::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHSet.hP b/gnu/lib/libg++/g++-include/gen/CHSet.hP new file mode 100644 index 0000000000..f0a08de4ce --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHSet.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _CHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _CHSet_h 1 + +#include ".Set.h" +#include ".CHNode.h" + +class CHSet : public Set +{ +protected: + CHNode** tab; + unsigned int size; + +public: + CHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + CHSet(CHSet& a); + ~CHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (CHSet& b); + void operator -= (CHSet& b); + void operator &= (CHSet& b); + + int operator == (CHSet& b); + int operator != (CHSet& b); + int operator <= (CHSet& b); + + int OK(); +}; + +inline CHSet::~CHSet() +{ + clear(); + delete tab; +} + +inline int CHSet::contains( key) +{ + return seek(key) != 0; +} + +inline & CHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((CHNode*)i)->hd; +} + +inline int CHSet::operator != (CHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.ccP b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP new file mode 100644 index 0000000000..d5a0db7f91 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".DLDeque.h" diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.hP b/gnu/lib/libg++/g++-include/gen/DLDeque.hP new file mode 100644 index 0000000000..d91cdd41cb --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLDeque.hP @@ -0,0 +1,130 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _DLDeque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _DLDeque_h + +#include ".DLList.h" +#include ".Deque.h" + +class DLDeque : public Deque +{ + DLList p; + +public: + DLDeque(); + DLDeque(const DLDeque& d); + ~DLDeque(); + + void operator = (const DLDeque&); + + void push( item); // insert at front + void enq( item); // insert at rear + + & front(); + & rear(); + + deq(); + void del_front(); + void del_rear(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + + +inline DLDeque::DLDeque() : p() {} +inline DLDeque::DLDeque(const DLDeque& d) : p(d.p) {} + +inline DLDeque::~DLDeque() {} + +inline void DLDeque::push(item) +{ + p.prepend(item); +} + +inline void DLDeque::enq(item) +{ + p.append(item); +} + +inline DLDeque::deq() +{ + return p.remove_front(); +} + +inline & DLDeque::front() +{ + return p.front(); +} + +inline & DLDeque::rear() +{ + return p.rear(); +} + +inline void DLDeque::del_front() +{ + p.del_front(); +} + +inline void DLDeque::del_rear() +{ + p.del_rear(); +} + +inline void DLDeque::operator =(const DLDeque& s) +{ + p.operator = (s.p); +} + + +inline int DLDeque::empty() +{ + return p.empty(); +} + +inline int DLDeque::full() +{ + return 0; +} + +inline int DLDeque::length() +{ + return p.length(); +} + +inline int DLDeque::OK() +{ + return p.OK(); +} + +inline void DLDeque::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/DLList.ccP b/gnu/lib/libg++/g++-include/gen/DLList.ccP new file mode 100644 index 0000000000..cb1e22a337 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLList.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include +#include ".DLList.h" + +// error handling + + + +void DLList::error(const char* msg) +{ + (*lib_error_handler)("DLList", msg); +} + +int DLList::length() +{ + int l = 0; + DLListNode* t = h; + if (t != 0) do { ++l; t = t->fd; } while (t != h); + return l; +} + +DLList::DLList(const DLList& a) +{ + if (a.h == 0) + h = 0; + else + { + DLListNode* p = a.h; + DLListNode* t = new DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + DLListNode* n = new DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + return; + } +} + +DLList& DLList::operator = (const DLList& a) +{ + if (h != a.h) + { + clear(); + if (a.h != 0) + { + DLListNode* p = a.h; + DLListNode* t = new DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + DLListNode* n = new DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + } + } + return *this; +} + +void DLList::clear() +{ + if (h == 0) + return; + + DLListNode* p = h->fd; + h->fd = 0; + h = 0; + + while (p != 0) + { + DLListNode* nxt = p->fd; + delete(p); + p = nxt; + } +} + + +Pix DLList::prepend( item) +{ + DLListNode* t = new DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->fd = h; + t->bk = h->bk; + h->bk->fd = t; + h->bk = t; + h = t; + } + return Pix(t); +} + +Pix DLList::append( item) +{ + DLListNode* t = new DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->bk = h->bk; + t->bk->fd = t; + t->fd = h; + h->bk = t; + } + return Pix(t); +} + +Pix DLList::ins_after(Pix p, item) +{ + if (p == 0) return prepend(item); + DLListNode* u = (DLListNode*) p; + DLListNode* t = new DLListNode(item, u, u->fd); + u->fd->bk = t; + u->fd = t; + return Pix(t); +} + +Pix DLList::ins_before(Pix p, item) +{ + if (p == 0) error("null Pix"); + DLListNode* u = (DLListNode*) p; + DLListNode* t = new DLListNode(item, u->bk, u); + u->bk->fd = t; + u->bk = t; + if (u == h) h = t; + return Pix(t); +} + +void DLList::join(DLList& b) +{ + DLListNode* t = b.h; + b.h = 0; + if (h == 0) + h = t; + else if (t != 0) + { + DLListNode* l = t->bk; + h->bk->fd = t; + t->bk = h->bk; + h->bk = l; + l->fd = h; + } +} + +int DLList::owns(Pix p) +{ + DLListNode* t = h; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->fd; + } while (t != h); + } + return 0; +} + +void DLList::del(Pix& p, int dir) +{ + if (p == 0) error("null Pix"); + DLListNode* t = (DLListNode*) p; + if (t->fd == t) + { + h = 0; + p = 0; + } + else + { + if (dir < 0) + { + if (t == h) + p = 0; + else + p = Pix(t->bk); + } + else + { + if (t == h->bk) + p = 0; + else + p = Pix(t->fd); + } + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + +void DLList::del_after(Pix& p) +{ + if (p == 0) + { + del_front(); + return; + } + + DLListNode* b = (DLListNode*) p; + DLListNode* t = b->fd; + + if (b == t) + { + h = 0; + p = 0; + } + else + { + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + + DLList::remove_front() +{ + if (h == 0) + error("remove_front of empty list"); + DLListNode* t = h; + res = t->hd; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; + return res; +} + + +void DLList::del_front() +{ + if (h == 0) + error("del_front of empty list"); + DLListNode* t = h; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; +} + + DLList::remove_rear() +{ + if (h == 0) + error("remove_rear of empty list"); + DLListNode* t = h->bk; + res = t->hd; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; + return res; +} + + +void DLList::del_rear() +{ + if (h == 0) + error("del_rear of empty list"); + DLListNode* t = h->bk; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; +} + + +int DLList::OK() +{ + int v = 1; + if (h != 0) + { + DLListNode* t = h; + long count = MAXLONG; // Lots of chances to find h! + do + { + count--; + v &= t->bk->fd == t; + v &= t->fd->bk == t; + t = t->fd; + } while (v && count > 0 && t != h); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/DLList.hP b/gnu/lib/libg++/g++-include/gen/DLList.hP new file mode 100644 index 0000000000..b115ab9f6f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLList.hP @@ -0,0 +1,157 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _DLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _DLList_h 1 + +#include +#include ".defs.h" + +#ifndef _DLListNode_h +#define _DLListNode_h 1 + +struct DLListNode +{ + DLListNode* bk; + DLListNode* fd; + hd; + DLListNode(); + DLListNode(const h, + DLListNode* p = 0, + DLListNode* n = 0); + ~DLListNode(); +}; + +inline DLListNode::DLListNode() {} + +inline DLListNode::DLListNode(const h, DLListNode* p, + DLListNode* n) + :hd(h), bk(p), fd(n) {} + +inline DLListNode::~DLListNode() {} + +typedef DLListNode* DLListNodePtr; + +#endif + +class DLList +{ + friend class DLListTrav; + + DLListNode* h; + +public: + DLList(); + DLList(const DLList& a); + ~DLList(); + + DLList& operator = (const DLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend( item); + Pix append( item); + void join(DLList&); + + & front(); + remove_front(); + void del_front(); + + & rear(); + remove_rear(); + void del_rear(); + + & operator () (Pix p); + Pix first(); + Pix last(); + void next(Pix& p); + void prev(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, item); + Pix ins_before(Pix p, item); + void del(Pix& p, int dir = 1); + void del_after(Pix& p); + + void error(const char* msg); + int OK(); +}; + + +inline DLList::~DLList() +{ + clear(); +} + +inline DLList::DLList() +{ + h = 0; +} + +inline int DLList::empty() +{ + return h == 0; +} + + +inline void DLList::next(Pix& p) +{ + p = (p == 0 || p == h->bk)? 0 : Pix(((DLListNode*)p)->fd); +} + +inline void DLList::prev(Pix& p) +{ + p = (p == 0 || p == h)? 0 : Pix(((DLListNode*)p)->bk); +} + +inline Pix DLList::first() +{ + return Pix(h); +} + +inline Pix DLList::last() +{ + return (h == 0)? 0 : Pix(h->bk); +} + +inline & DLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((DLListNode*)p)->hd; +} + +inline & DLList::front() +{ + if (h == 0) error("front: empty list"); + return h->hd; +} + +inline & DLList::rear() +{ + if (h == 0) error("rear: empty list"); + return h->bk->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Deque.ccP b/gnu/lib/libg++/g++-include/gen/Deque.ccP new file mode 100644 index 0000000000..79a9b72c87 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Deque.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Deque.h" + +Deque::~Deque() {} + +void Deque::error(const char* msg) +{ + (*lib_error_handler)("Deque", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Deque.hP b/gnu/lib/libg++/g++-include/gen/Deque.hP new file mode 100644 index 0000000000..7ec52d4a0c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Deque.hP @@ -0,0 +1,57 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Deque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Deque_h + +#include + +#include ".defs.h" + +class Deque +{ +public: + Deque() { } + virtual ~Deque(); + + virtual void push( item) = 0; // insert at front + virtual void enq( item) = 0; // insert at rear + + virtual & front() = 0; + virtual & rear() = 0; + + virtual deq() = 0; + virtual void del_front() = 0; + virtual void del_rear() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + virtual void clear() = 0; + + virtual int OK() = 0; + + void error(const char*); +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.ccP b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP new file mode 100644 index 0000000000..a358cacb60 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPQueue.h" diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.hP b/gnu/lib/libg++/g++-include/gen/FPQueue.hP new file mode 100644 index 0000000000..f647ae9dfd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPQueue.hP @@ -0,0 +1,112 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _FPQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPQueue_h + +#include ".FPlex.h" +#include ".Queue.h" + +class FPQueue : public Queue +{ + FPlex p; + +public: + FPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY); + FPQueue(const FPQueue& q); + ~FPQueue(); + + void operator = (const FPQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline FPQueue::FPQueue(int chunksize) : p(chunksize) {} +inline FPQueue::FPQueue(const FPQueue& q) : p(q.p) {} + +inline FPQueue::~FPQueue() {} + +inline void FPQueue::enq(item) +{ + p.add_high(item); +} + +inline FPQueue::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & FPQueue::front() +{ + return p.low_element(); +} + + +inline void FPQueue::del_front() +{ + p.del_low(); +} + +inline void FPQueue::operator =(const FPQueue& s) +{ + p = s.p; +} + +inline int FPQueue::empty() +{ + return p.empty(); +} + +inline int FPQueue::full() +{ + return p.full(); +} + +inline int FPQueue::length() +{ + return p.length(); +} + +inline int FPQueue::OK() +{ + return p.OK(); +} + +inline void FPQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.ccP b/gnu/lib/libg++/g++-include/gen/FPStack.ccP new file mode 100644 index 0000000000..954991193b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPStack.h" diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.hP b/gnu/lib/libg++/g++-include/gen/FPStack.hP new file mode 100644 index 0000000000..091f255360 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPStack.hP @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _FPStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPStack_h + +#include ".FPlex.h" +#include ".Stack.h" + +class FPStack : public Stack +{ + FPlex p; + +public: + FPStack(int chunksize = DEFAULT_INITIAL_CAPACITY); + FPStack(const FPStack& s); + ~FPStack(); + + void operator = (const FPStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + + +inline FPStack::FPStack(int chunksize) : p(chunksize) {} +inline FPStack::FPStack(const FPStack& s) : p(s.p) {} + +inline FPStack::~FPStack() {} + +inline void FPStack::push(item) +{ + p.add_high(item); +} + +inline FPStack::pop() +{ + res = p.high_element(); + p.del_high(); + return res; +} + +inline & FPStack::top() +{ + return p.high_element(); +} + +inline void FPStack::del_top() +{ + p.del_high(); +} + +inline void FPStack::operator =(const FPStack& s) +{ + p = s.p; +} + +inline int FPStack::empty() +{ + return p.empty(); +} + +inline int FPStack::full() +{ + return p.full(); +} + +inline int FPStack::length() +{ + return p.length(); +} + +inline int FPStack::OK() +{ + return p.OK(); +} + +inline void FPStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPlex.ccP b/gnu/lib/libg++/g++-include/gen/FPlex.ccP new file mode 100644 index 0000000000..70d6c47557 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPlex.ccP @@ -0,0 +1,167 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".FPlex.h" + + +FPlex:: FPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); +} + +FPlex:: FPlex(int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (maxsize > 0) + { + csize = maxsize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + * data = new [csize]; + hd = new IChunk(data, maxsize, lo, fnc, fnc); + } +} + + +FPlex:: FPlex(int l, int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (maxsize > 0) + { + csize = maxsize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -maxsize; + * data = new [csize]; + hd = new IChunk(data, maxsize+lo, lo, fnc, fnc); + } +} + +FPlex:: FPlex(int l, int hi, const initval, int maxsize) +{ + lo = l; + fnc = hi + 1; + if (maxsize >= 0) + { + csize = maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + * data = new [csize]; + hd = new IChunk(data, -csize, lo, fnc, fnc); + } + fill(initval); +} + +FPlex::FPlex(const FPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void FPlex::operator= (const FPlex& a) +{ + if (&a != this) + { + del_chunk(hd); + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + * data = new [csize]; + hd = new IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void FPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + +void FPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void FPlex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + +void FPlex::clear() +{ + if (fnc != lo) + { + hd->clear(lo); + fnc = lo; + } +} + +int FPlex::OK () const +{ + int v = hd != 0; // hd exists + v &= hd->IChunk::OK(); // and is OK + v &= fnc - lo <= hd->size(); // and has enough space + v &= lo <= fnc; // plex indices consistent + v &= lo == hd->low_index(); // and match those + v &= fnc == hd->fence_index(); // of chunk + v &= one_chunk(); // and only one chunk + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/FPlex.hP b/gnu/lib/libg++/g++-include/gen/FPlex.hP new file mode 100644 index 0000000000..eb93a0c372 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPlex.hP @@ -0,0 +1,253 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _FPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _FPlex_h 1 + +#include ".Plex.h" + +class FPlex : public Plex +{ +public: + FPlex(); // set low = 0; + // fence = 0; + // csize = default + + FPlex(int maxsize); // low = 0; + // fence = 0; + // csize = maxsize + + FPlex(int lo, // low = lo; + int maxsize); // fence=lo + // csize = maxsize + + FPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int maxsize = 0); // csize = maxsize + // or fence - lo if 0 + + FPlex(const FPlex&); // X(X&) + + ~FPlex(); + + void operator= (const FPlex&); + +// virtuals + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int OK () const; +}; + + +inline int FPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int FPlex::low() const +{ + return lo; +} + +inline int FPlex::high() const +{ + return fnc - 1; +} + +inline Pix FPlex::first() const +{ + return (Pix)(hd->IChunk::first_pointer()); +} + +inline void FPlex::prev(Pix& p) const +{ + p = Pix(hd->IChunk::pred((*) p)); +} + +inline void FPlex::next(Pix& p) const +{ + p = Pix(hd->IChunk::succ((*) p)); +} + +inline Pix FPlex::last() const +{ + return Pix(hd->IChunk::last_pointer()); +} + +inline int FPlex::full () const +{ + return fnc - lo == csize; +} + +inline void FPlex::prev(int& idx) const +{ + --idx; +} + +inline void FPlex::next(int& idx) const +{ + ++idx; +} + +inline & FPlex:: operator [] (int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline & FPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline & FPlex::low_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline & FPlex::high_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline const & FPlex:: operator [] (int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline const & FPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline const & FPlex::low_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline const & FPlex::high_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline int FPlex::can_add_high() const +{ + return hd->can_grow_high(); +} + +inline int FPlex::can_add_low() const +{ + return hd->can_grow_low(); +} + +inline int FPlex::add_high(const elem) +{ + if (!can_add_high()) full_error(); + *((hd->IChunk::grow_high())) = elem; + return fnc++; +} + +inline int FPlex::del_high () +{ + if (empty()) empty_error(); + hd->IChunk::shrink_high(); + return --fnc - 1; +} + +inline int FPlex::add_low (const elem) +{ + if (!can_add_low()) full_error(); + *((hd->IChunk::grow_low())) = elem; + return --lo; +} + +inline int FPlex::del_low () +{ + if (empty()) empty_error(); + hd->IChunk::shrink_low(); + return ++lo; +} + +inline int FPlex::owns (Pix p) const +{ + return hd->actual_pointer((*)p); +} + +inline int FPlex::Pix_to_index(Pix p) const +{ + if (!hd->actual_pointer((const *)p)) index_error(); + return hd->index_of((const *)p); +} + +inline Pix FPlex::index_to_Pix(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return Pix(hd->pointer_to(idx)); +} + +inline FPlex::~FPlex() {} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/List.ccP b/gnu/lib/libg++/g++-include/gen/List.ccP new file mode 100644 index 0000000000..2afbdaf972 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/List.ccP @@ -0,0 +1,956 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".List.h" + +ListNode NilListNode; + +class init_NilListNode +{ +public: + init_NilListNode() + { + NilListNode.tl = &NilListNode; + NilListNode.ref = -1; + } +}; + +static init_NilListNode NilListNode_initializer; + +List& List::operator = (List& a) +{ + reference(a.P); + dereference(P); + P = a.P; + return *this; +} + + List::pop() +{ + res = P->hd; + ListNode* tail = P->tl; + reference(tail); + dereference(P); + P = tail; + return res; +} + +void List::set_tail(List& a) +{ + reference(a.P); + dereference(P->tl); + P->tl = a.P; +} + +List List::nth(int n) +{ + for (ListNode* p = P; n-- > 0; p = p->tl); + reference(p); + return List(p); +} + +List List::last() +{ + ListNode* p = P; + if (p != &NilListNode) while (p->tl != &NilListNode) p = p->tl; + reference(p); + return List(p); +} + +void List::append(List& l) +{ + ListNode* p = P; + ListNode* a = l.P; + reference(a); + if (p != &NilListNode) + { + while (p->tl != &NilListNode) p = p->tl; + p->tl = a; + } + else + P = a; +} + +int List::length() +{ + int l = 0; + for (ListNode* p = P; p != &NilListNode; p = p->tl) ++l; + return l; +} + +& List::operator [] (int n) +{ + for (ListNode* p = P; n-- > 0; p = p->tl); + return (p->hd); +} + +int operator == (List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + + for (;;) + { + if (a == &NilListNode) + return b == &NilListNode; + else if (b == &NilListNode) + return 0; + else if (EQ(a->hd, b->hd)) + { + a = a->tl; + b = b->tl; + } + else + return 0; + } +} + + +void List::apply(Procedure f) +{ + for(ListNode* p = P; p != &NilListNode; p = p->tl) + (*f)((p->hd)); +} + +void List::subst( old, repl) +{ + for(ListNode* p = P; p != &NilListNode; p = p->tl) + if (EQ(p->hd, old)) + p->hd = repl; +} + + List::reduce(Combiner f, base) +{ + r = base; + for(ListNode* p = P; p != &NilListNode; p = p->tl) + r = (*f)(r, (p->hd)); + return r; +} + +int List::position( targ) +{ + int l = 0; + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return -1; + else if (EQ(p->hd, targ)) + return l; + else + { + ++l; + p = p->tl; + } + } +} + +int List::contains( targ) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (EQ(p->hd, targ)) + return 1; + else + p = p->tl; + } +} + +List List::find( targ) +{ + ListNode* p = P; + while (p != &NilListNode && !EQ(p->hd, targ)) + p=p->tl; + reference(p); + return List(p); +} + +Pix List::seek( targ) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (EQ(p->hd, targ)) + return Pix(p); + else + p = p->tl; + } +} + +int List::owns(Pix i) +{ + ListNode* p = P; + for (;;) + { + if (p == &NilListNode) + return 0; + else if (Pix(p) == i) + return 1; + else + p = p->tl; + } +} + +List List::find(List& target) +{ + ListNode* targ = target.P; + if (targ == &NilListNode) + return List(targ); + + ListNode* p = P; + while (p != &NilListNode) + { + if (EQ(p->hd, targ->hd)) + { + ListNode* a = p->tl; + ListNode* t = targ->tl; + for(;;) + { + if (t == &NilListNode) + { + reference(p); + return List(p); + } + else if (a == &NilListNode || !EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return List(&NilListNode); +} + +int List::contains(List& target) +{ + ListNode* targ = target.P; + if (targ == &NilListNode) + return 0; + + ListNode* p = P; + while (p != &NilListNode) + { + if (EQ(p->hd, targ->hd)) + { + ListNode* a = p->tl; + ListNode* t = targ->tl; + for(;;) + { + if (t == &NilListNode) + return 1; + else if (a == &NilListNode || !EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return 0; +} + +void List::del( targ) +{ + ListNode* h = P; + + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if (EQ(h->hd, targ)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if (EQ(p->hd, targ)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::del(Predicate f) +{ + ListNode* h = P; + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if ((*f)(h->hd)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if ((*f)(p->hd)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::select(Predicate f) +{ + ListNode* h = P; + for (;;) + { + if (h == &NilListNode) + { + P = h; + return; + } + else if (!(*f)(h->hd)) + { + ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + ListNode* trail = h; + ListNode* p = h->tl; + while (p != &NilListNode) + { + if (!(*f)(p->hd)) + { + ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void List::reverse() +{ + ListNode* l = &NilListNode; + ListNode* p = P; + while (p != &NilListNode) + { + ListNode* nxt = p->tl; + p->tl = l; + l = p; + p = nxt; + } + P = l; +} + + +List copy(List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } +} + + +List subst( old, repl, List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* h = new ListNode; + h->ref = 1; + if (EQ(a->hd, old)) + h->hd = repl; + else + h->hd = a->hd; + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = new ListNode; + n->ref = 1; + if (EQ(a->hd, old)) + n->hd = repl; + else + n->hd = a->hd; + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } +} + +List combine(Combiner f, List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + if (a == &NilListNode || b == &NilListNode) + return List(&NilListNode); + else + { + ListNode* h = newListNode((*f)(a->hd, b->hd)); + ListNode* trail = h; + a = a->tl; + b = b->tl; + while (a != &NilListNode && b != &NilListNode) + { + ListNode* n = newListNode((*f)(a->hd, b->hd)); + trail->tl = n; + trail = n; + a = a->tl; + b = b->tl; + } + trail->tl = &NilListNode; + return List(h); + } +} + +List reverse(List& x) +{ + ListNode* a = x.P; + if (a == &NilListNode) + return List(a); + else + { + ListNode* l = newListNode(a->hd); + l->tl = &NilListNode; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + n->tl = l; + l = n; + } + return List(l); + } +} + +List append(List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + reference(b); + if (a != &NilListNode) + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = b; + return List(h); + } + else + return List(b); +} + +void List::prepend(List& y) +{ + ListNode* b = y.P; + if (b != &NilListNode) + { + ListNode* h = newListNode(b->hd); + ListNode* trail = h; + for(b = b->tl; b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = P; + P = h; + } +} + +List concat(List& x, List& y) +{ + ListNode* a = x.P; + ListNode* b = y.P; + if (a != &NilListNode) + { + ListNode* h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + }; + for(;b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } + else if (b != &NilListNode) + { + ListNode* h = newListNode(b->hd); + ListNode* trail = h; + for(b = b->tl; b != &NilListNode; b = b->tl) + { + ListNode* n = newListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + return List(h); + } + else + return List(&NilListNode); +} + +List select(Predicate f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if ((*f)(a->hd)) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if ((*f)(a->hd)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List remove(Predicate f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if (!(*f)(a->hd)) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if (!(*f)(a->hd)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List remove( targ, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + while (a != &NilListNode) + { + if (!(EQ(a->hd, targ))) + { + h = newListNode(a->hd); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + if (!EQ(a->hd, targ)) + { + ListNode* n = newListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &NilListNode; + break; + } + else + a = a->tl; + } + return List(h); +} + +List map(Mapper f, List& x) +{ + ListNode* a = x.P; + ListNode* h = &NilListNode; + if (a != &NilListNode) + { + h = newListNode((*f)(a->hd)); + ListNode* trail = h; + for(a = a->tl; a != &NilListNode; a = a->tl) + { + ListNode* n = newListNode((*f)(a->hd)); + trail->tl = n; + trail = n; + } + trail->tl = &NilListNode; + } + return List(h); +} + + +List merge(List& x, List& y, Comparator f) +{ + ListNode* a = x.P; + ListNode* b = y.P; + + if (a == &NilListNode) + { + if (b == &NilListNode) + return List(&NilListNode); + else + return copy(y); + } + else if (b == &NilListNode) + return copy(x); + + ListNode* h = new ListNode; + h->ref = 1; + if ((*f)(a->hd, b->hd) <= 0) + { + h->hd = a->hd; + a = a->tl; + } + else + { + h->hd = b->hd; + b = b->tl; + } + + ListNode* r = h; + + for(;;) + { + if (a == &NilListNode) + { + while (b != &NilListNode) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + r->tl = &NilListNode; + return List(h); + } + else if (b == &NilListNode) + { + while (a != &NilListNode) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + r->tl = &NilListNode; + return List(h); + } + else if ((*f)(a->hd, b->hd) <= 0) + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + else + { + ListNode* n = new ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + } +} + +void List::sort(Comparator f) +{ + // strategy: place runs in queue, merge runs until done + // This is often very fast + + if (P == &NilListNode || P->tl == &NilListNode) + return; + + int qlen = 250; // guess a good queue size, realloc if necessary + + ListNode** queue = (ListNode**)malloc(qlen * sizeof(ListNode*)); + + ListNode* h = P; + ListNode* a = h; + ListNode* b = a->tl; + int qin = 0; + + while (b != &NilListNode) + { + if ((*f)(a->hd, b->hd) > 0) + { + if (h == a) // minor optimization: ensure runlen >= 2 + { + h = b; + a->tl = b->tl; + b->tl = a; + b = a->tl; + } + else + { + if (qin >= qlen) + { + qlen *= 2; + queue = (ListNode**)realloc(queue, qlen * sizeof(ListNode*)); + } + queue[qin++] = h; + a->tl = &NilListNode; + h = a = b; + b = b->tl; + } + } + else + { + a = b; + b = b->tl; + } + } + + int count = qin; + queue[qin] = h; + if (++qin >= qlen) qin = 0; + int qout = 0; + + while (count-- > 0) + { + a = queue[qout]; + if (++qout >= qlen) qout = 0; + b = queue[qout]; + if (++qout >= qlen) qout = 0; + + if ((*f)(a->hd, b->hd) <= 0) + { + h = a; + a = a->tl; + } + else + { + h = b; + b = b->tl; + } + queue[qin] = h; + if (++qin >= qlen) qin = 0; + + for (;;) + { + if (a == &NilListNode) + { + h->tl = b; + break; + } + else if (b == &NilListNode) + { + h->tl = a; + break; + } + else if ((*f)(a->hd, b->hd) <= 0) + { + h->tl = a; + h = a; + a = a->tl; + } + else + { + h->tl = b; + h = b; + b = b->tl; + } + } + } + P = queue[qout]; + free(queue); +} + +int List::list_length() +{ + ListNode* fast = P; + if (fast == &NilListNode) + return 0; + + ListNode* slow = fast->tl; + if (slow == &NilListNode) + return 1; + + fast = slow->tl; + int n = 2; + + for (;;) + { + if (fast == &NilListNode) + return n; + else if (fast->tl == &NilListNode) + return n+1; + else if (fast == slow) + return -1; + else + { + n += 2; + fast = fast->tl->tl; + slow = slow->tl; + } + } +} + +void List::error(const char* msg) +{ + (*lib_error_handler)("List", msg); +} + +int List::OK() +{ + int v = P != 0; // have a node + // check that all nodes OK, even if circular: + + ListNode* fast = P; + if (fast != &NilListNode) + { + v &= fast->ref != 0; + ListNode* slow = fast->tl; + v &= slow->ref != 0; + if (v && slow != &NilListNode) + { + fast = slow->tl; + v &= fast->ref != 0; + while (v) + { + if (fast == &NilListNode) + break; + else if (fast->tl == &NilListNode) + break; + else if (fast == slow) + break; + else + { + v &= fast->ref != 0 && slow->ref != 0; + fast = fast->tl->tl; + slow = slow->tl; + } + } + } + } + if (!v) error ("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/List.hP b/gnu/lib/libg++/g++-include/gen/List.hP new file mode 100644 index 0000000000..7ccdbc3bc4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/List.hP @@ -0,0 +1,273 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _List_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _List_h 1 + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)(); +typedef (*Mapper)(); +typedef (*Combiner)(, ); +typedef int (*Predicate)(); +typedef int (*Comparator)(, ); +#endif + +#include +#include ".defs.h" + +struct ListNode +{ + ListNode* tl; + short ref; + hd; +}; + +extern ListNode NilListNode; + +class List +{ +protected: + ListNode* P; + + List(ListNode* p); +public: + List(); + List( head); + List( head, List& tl); + List(List& a); + List(Pix p); + ~List(); + + List& operator = (List& a); + + int null(); + int valid(); + operator const void* (); + int operator ! (); + + int length(); + int list_length(); + + & get(); + & head(); + & operator [] (int n); + + List nth(int n); + List tail(); + List last(); + + List find( targ); + List find(List& targ); + int contains( targ); + int contains(List& targ); + int position( targ); + + friend List copy(List& a); + friend List concat(List& a, List& b); + friend List append(List& a, List& b); + friend List map(Mapper f, List& a); + friend List merge(List& a, List& b, Comparator f); + friend List combine(Combiner f, List& a, List& b); + friend List reverse(List& a); + friend List select(Predicate f, List& a); +#undef remove + friend List remove( targ, List& a); + friend List remove(Predicate f, List& a); + friend List subst( old, repl, List& a); + + void push( x); + pop(); + + void set_tail(List& p); + void append(List& p); + void prepend(List& p); + void del( targ); + void del(Predicate f); + void select(Predicate f); + void subst( old, repl); + void reverse(); + void sort(Comparator f); + + void apply(Procedure f); + reduce(Combiner f, base); + + friend int operator == (List& a, List& b); + friend int operator != (List& a, List& b); + + Pix first(); + void next(Pix& p); + Pix seek( item); + & operator () (Pix p); + int owns(Pix p); + + void error(const char*); + int OK(); +}; + + +inline void reference(ListNode* p) +{ + if (p->ref >= 0) ++p->ref; +} + +inline void dereference(ListNode* p) +{ + while (p->ref > 0 && --p->ref == 0) + { + ListNode* n = p->tl; + delete(p); + p = n; + } +} + + +inline ListNode* newListNode( h) +{ + ListNode* p = new ListNode; + p->ref = 1; + p->hd = h; + return p; +} + +inline ListNode* newListNode( h, ListNode* t) +{ + ListNode* p = new ListNode; + p->ref = 1; + p->hd = h; + p->tl = t; + return p; +} + + +inline List::~List() +{ + dereference(P); +} + +inline List::List() +{ + P = &NilListNode; +} + +inline List::List(ListNode* p) +{ + P = p; +} + +inline List::List( head) +{ + P = newListNode(head); + P->tl = &NilListNode; +} + +inline List::List( head, List& tl) +{ + P = newListNode(head, tl.P); + reference(P->tl); +} + +inline List::List(List& a) +{ + reference(a.P); + P = a.P; +} + + +inline & List::get() +{ + return P->hd; +} + +inline & List::head() +{ + return P->hd; +} + + +inline List List::tail() +{ + reference(P->tl); + return List(P->tl); +} + + + +inline int List::null() +{ + return P == &NilListNode; +} + +inline int List::valid() +{ + return P != &NilListNode; +} + +inline List::operator const void* () +{ + return (P == &NilListNode)? 0 : this; +} + +inline int List::operator ! () +{ + return (P == &NilListNode); +} + + +inline void List::push( head) +{ + ListNode* oldp = P; + P = newListNode(head, oldp); +} + + +inline int operator != (List& x, List& y) +{ + return !(x == y); +} + +inline Pix List::first() +{ + return (P == &NilListNode)? 0 : Pix(P); +} + +inline & List::operator () (Pix p) +{ + return ((ListNode*)p)->hd; +} + +inline void List::next(Pix& p) +{ + if (p != 0) + { + p = Pix(((ListNode*)p)->tl); + if (p == &NilListNode) p = 0; + } +} + +inline List::List(Pix p) +{ + P = (ListNode*)p; + reference(P); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/MPlex.ccP b/gnu/lib/libg++/g++-include/gen/MPlex.ccP new file mode 100644 index 0000000000..89a1bcf9e6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/MPlex.ccP @@ -0,0 +1,845 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".MPlex.h" + +// MChunk support + + +MChunk::MChunk(* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) + : IChunk(d, baseidx, lowidx, fenceidx, topidx) +{ + unused = fence - low; + unsigned msize = (top - base)/_MAP_BITS + 1; + map = (unsigned long *) (new long[msize]); + memset((void*)map, 0, msize * sizeof(long)); +} + +void MChunk:: shrink_high () +{ + if (fence <= low) empty_error(); + --fence; + if (!valid(fence)) + --unused; + else + free(fence); + reset_high(); +} + +void MChunk:: shrink_low () +{ + if (fence <= low) empty_error(); + if (!valid(low)) + --unused; + else + free(low); + ++low; + reset_low(); +} + +void MChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +void MChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +int MChunk::del(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (v) + { + free(idx); + ++unused; + } + return v; +} + + +int MChunk::undel(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (!v) + { + mark(idx); + --unused; + } + return v; +} + +int MChunk::unused_index() const +{ + if (unused_indices() == 0) index_error(); + int slot; + if (low == base) // can traverse 32 slots at a time + { + int blk = 0; + while (map[blk] == ~0L) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(valid(slot)) ++slot; + return slot; +} + +int MChunk::first_index() const +{ + if (empty()) return fence; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return slot; +} + +int MChunk::last_index() const +{ + if (empty()) return low - 1; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return slot; +} + + +int MChunk:: OK() const +{ + int v = data != 0; // have some data + v &= map != 0; // and a map + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= ((MChunk*)(nxt->prev())) == this; // and links are OK + v &= ((MChunk*)(prv->next())) == this; + + int bitcount = 0; // and unused count correct + for (int i = low; i < fence; ++i) if (!valid(i)) ++bitcount; + v &= unused == bitcount; + + if (!v) error("invariant failure"); + return(v); +} + +* MChunk::succ(* p) const +{ + int i = ((int) p - (int) data) / sizeof() + base + 1; + if (p == 0 || i < low) return 0; + while (i < fence && !valid(i)) ++i; + if (i >= fence) return 0; + return pointer_to(i); +} + +* MChunk::pred(* p) const +{ + int i = ((int) p - (int) data) / sizeof() + base - 1; + if (p == 0 || i >= fence) return 0; + while (i >= low && !valid(i)) --i; + if (i < low) return 0; + return pointer_to(i); +} + +* MChunk::first_pointer() const +{ + if (empty()) return 0; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return pointer_to(slot); +} + +* MChunk::last_pointer() const +{ + if (empty()) return 0; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return pointer_to(slot); +} + +MPlex:: MPlex() +{ + unused = 0; + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, lo+csize); +} + +MPlex:: MPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, chunksize, lo, fnc, fnc); + } +} + + +MPlex:: MPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -chunksize; + * data = new [csize]; + hd = ch = new MChunk(data, chunksize+lo, lo, fnc, fnc); + } +} + + +void MPlex::make_initial_chunks(int up) +{ + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + MChunk* h = new MChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + MChunk* h = new MChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + ch = (MChunk*) hd; +} + +MPlex:: MPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + unused = fnc - lo; + for (int i=lo; iMPlex::MPlex(const MPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const IChunk* p = a.hd; + do + { + * data = new [p->size()]; + MChunk* h = new MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } +} + +void MPlex::operator= (const MPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const IChunk* p = a.hd; + do + { + * data = new [p->size()]; + MChunk* h = new MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), + p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } + } +} + +int MPlex::valid(int idx) const +{ + const MChunk* tail = (MChunk*)tl(); + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) return 0; + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (MChunk*)(hd)) return 0; + t = ((MChunk*)(t->prev())); + } + set_cache(t); + return t->MChunk::valid_index(idx); +} + +void MPlex::cache(int idx) const +{ + const MChunk* tail = (MChunk*)tl(); + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) index_error(); + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (MChunk*)hd) index_error(); + t = ((MChunk*)(t->prev())); + } + if (!t->MChunk::valid_index(idx)) index_error(); + set_cache(t); +} + +void MPlex::cache(const * p) const +{ + const MChunk* old = ch; + const MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) index_error(); + } + if (!t->MChunk::valid_pointer(p)) index_error(); + set_cache(t); +} + +int MPlex::owns(Pix px) const +{ + * p = (*)px; + const MChunk* old = ch; + const MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) return 0; + } + set_cache(t); + return t->MChunk::valid_pointer(p); +} + +int MPlex::add_high(const elem) +{ + MChunk* t = ((MChunk*) tl()); + + if (!t->can_grow_high()) + { + * data = new [csize]; + t = (new MChunk(data, fnc,fnc,fnc,fnc+csize)); + t->link_to_prev(tl()); + } + + *((t->MChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int MPlex::add_low (const elem) +{ + MChunk* t = ((MChunk*) hd); + if (!t->can_grow_low()) + { + * data = new [csize]; + hd = new MChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ((MChunk*) hd); + } + + *((t->MChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + +void MPlex::adjust_bounds() +{ + MChunk* t = ((MChunk*) tl()); + + // clean up tail + + t->reset_high(); + while (t->MChunk::empty() && !one_chunk()) + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + if (one_chunk()) + t->reset_high(); + + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc; + + // and head.. + t = ((MChunk*) hd); + t->reset_low(); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo; + + + set_cache(t); +} + +int MPlex::del_high () +{ + if (empty()) empty_error(); + MChunk* t = ((MChunk*) tl()); + while (t->MChunk::empty() && !one_chunk()) // possible stragglers + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + t->MChunk::shrink_high(); + while (t->MChunk::empty() && !one_chunk()) + { + MChunk* pred = (MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc - 1; + set_cache(t); + return fnc - 1; +} + +int MPlex::del_low () +{ + if (empty()) empty_error(); + MChunk* t = ((MChunk*) hd); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + t->MChunk::shrink_low(); + while (t->MChunk::empty() && !one_chunk()) + { + hd = (MChunk*)(t->next()); + del_chunk(t); + t = ((MChunk*) hd); + t->reset_low(); + } + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo - 1; + set_cache(t); + return lo; +} + +int MPlex::add(const elem) +{ + if (unused == 0) + return add_high(elem); + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + int i = t->unused_index(); + set_cache(t); + undel_index(i); + (*this)[i] = elem; + return i; +} + +int MPlex::unused_index() const +{ + if (unused == 0) index_error(); + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + set_cache(t); + return t->unused_index(); +} + +Pix MPlex::unused_Pix() const +{ + if (unused == 0) return 0; + + for(MChunk* t = ch; + t->unused_indices() == 0; + t = (MChunk*)(t->prev())) + ; + + set_cache(t); + return t->pointer_to(t->unused_index()); +} + +int MPlex::del_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + if (MPlex::valid(idx)) + { + ++unused; + ch->MChunk::del(idx); + return 1; + } + else + return 0; +} + +int MPlex::dopred(int idx) const +{ + + if (idx >= fnc) idx = fnc; + if (idx <= lo) return lo - 1; + + const MChunk* t = ch; + + while (idx > t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx <= t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int i = t->MChunk::pred(idx); + while (i < t->low_index() && i >= lo) + { + t = ((MChunk*)(t->prev())); + i = t->MChunk::last_index(); + } + set_cache(t); + return i; +} + + +int MPlex::dosucc(int idx) const +{ + if (idx < lo) idx = lo; + if (idx >= fnc - 1) return fnc; + + const MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int i = t->MChunk::succ(idx); + while (i >= t->fence_index() && i < fnc) + { + t = (MChunk*)(t->next()); + i = t->MChunk::first_index(); + } + set_cache(t); + return i; +} + +void MPlex::prev(Pix& i) const +{ + if (i == 0) return; + + * p = (*) i; + const MChunk* old = ch; + const MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->prev())); + if (t == old) + { + i = 0; + return; + } + } + * q = t->MChunk::pred(p); + while (q == 0 && t != (MChunk*)hd) + { + t = ((MChunk*)(t->prev())); + q = t->MChunk::last_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + +void MPlex::next(Pix& i) const +{ + if (i == 0) return; + + * p = (*) i; + const MChunk* tail = (MChunk*)(tl()); + const MChunk* old = ch; + const MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((MChunk*)(t->next())); + if (t == old) + { + i = 0; + return; + } + } + * q = t->MChunk::succ(p); + while (q == 0 && t != tail) + { + t = ((MChunk*)(t->next())); + q = t->MChunk::first_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + + +void MPlex::undel_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + + MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((MChunk*)(t->prev())); + } + int was_present = t->MChunk::undel(idx); + if (!was_present) + { + --unused; + } + set_cache(t); + return; +} + +void MPlex::clear() +{ + if (fnc != lo) + { + MChunk* t = ((MChunk*)tl()); + while (t != hd) + { + MChunk* prv = (MChunk*)(t->prev()); + del_chunk(t); + t = prv; + } + t->MChunk::clear(lo); + set_cache(t); + fnc = lo; + unused = 0; + } +} + +int MPlex::OK () const +{ + int v = hd != 0; // at least one chunk + + int found_ch = 0; // to make sure ch is in list; + + int count = 0; // to count unused slots + + const MChunk* t = (MChunk*)(hd); + + int gap = t->low_index() - lo; + v &= gap == 0; // hd lo not less than lo. + count += gap; + + for (;;) + { + if (t == ch) ++found_ch; + v &= t->MChunk::OK(); // each chunk is OK + count += t->unused_indices(); + if (t == (MChunk*)(tl())) + break; + else // and has indices less than succ + { + gap = t->next()->base_index() - t->top_index(); + v &= gap == 0; + count += gap; + + if (t != (MChunk*)hd) // internal chunks can't grow + v &= !t->can_grow_low() && !t->can_grow_high(); + + t = (const MChunk*)(t->next()); + } + } + gap = fnc - t->fence_index(); + v &= gap == 0; + count += gap; + + v &= count == unused; // chunk counts agree with plex + + v &= found_ch == 1; + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/MPlex.hP b/gnu/lib/libg++/g++-include/gen/MPlex.hP new file mode 100644 index 0000000000..8bf78d13a1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/MPlex.hP @@ -0,0 +1,414 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _MPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _MPlex_h 1 + + +#include ".Plex.h" + + +// Number of bits per long, used in MChunk bit map operations + +#define _MAP_BITS 32 + + +class MChunk : public IChunk +{ +protected: + + unsigned long* map; // bitmap of slots + int unused; // number of unused internal slots + + void mark(int); // bitmap operations + void free(int); + int valid(int) const; + +public: + + MChunk(* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, // & initially clear map + int fence_idx, + int top_idx); + + ~MChunk(); + +// virtuals + + int first_index() const; + int last_index() const; + int succ(int idx) const; + int pred(int idx) const; + * first_pointer() const; + * last_pointer() const; + * succ(*) const; + * pred(*) const; + int empty() const; + int full() const; + int valid_index(int i) const; + int valid_pointer(const * p) const; + * grow_high (); + * grow_low (); + void shrink_high (); + void shrink_low (); + void clear(int); + void cleardown(int); + int OK() const; + +// extensions + + int unused_indices() const; // how many free slot in low..fence? + + int unused_index() const; // return index of free slot + + int del(int i); // delete data indexed by i + // return true if was present + int undel(int idx); // un-delete data indexed by i + // return true if already present + + void reset_low(); // reset low = lowest valid index; + void reset_high(); // same for high + +}; + + +class MPlex: public Plex +{ + MChunk* ch; // cached chunk + int unused; // # of free slots between low & fence + + void make_initial_chunks(int up = 1); + void cache(int idx) const; + void cache(const * p) const; + int dopred(int) const; + int dosucc(int) const; + + void set_cache(const MChunk* t) const; // logically, + // not physically const + +public: + MPlex(); // set low = 0; + // fence = 0; + // csize = default + + MPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + MPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + MPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + MPlex(const MPlex&); + + void operator= (const MPlex&); + +// virtuals + + & high_element (); + & low_element (); + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const ; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + void clear(); + + int OK () const; + +// extensions + + int count() const; // # valid elements + int available() const; // # deleted elements + + int unused_index()const; // return index of a deleted elem + Pix unused_Pix() const; // return Pix of a deleted elem + + int del_index(int idx); // logically delete at idx; + // return true if was present + int del_Pix(Pix p); // delete at p + + void undel_index(int idx); // undelete at idx; + void undel_Pix(Pix p); // undelete at p; + + void adjust_bounds(); // reset lo, hi to lowest & + // highest valid indices + + int add(const elem); // add anywhere +}; + + +inline MChunk:: ~MChunk() +{ + delete map; +} + +inline void MChunk::mark(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] |= 1 << (i & (_MAP_BITS - 1)); +} + +inline void MChunk::free(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] &= ~(1 << (i & (_MAP_BITS - 1))); +} + +inline int MChunk::valid(int idx) const +{ + unsigned int i = idx - base; + return map[i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1))); +} + +inline int MChunk:: valid_index(int i) const +{ + return i >= low && i < fence && valid(i); +} + +inline int MChunk:: valid_pointer(const * p) const +{ + int i = ((int)p - (int)data) / sizeof(); + return i >= 0 && i < (fence - base) && + (map[(unsigned)i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1)))); +} + +inline int MChunk::empty() const +{ + return fence - low - unused == 0; +} + +inline int MChunk::full() const +{ + return unused + (top - fence) + (low - base) == 0; +} + +inline int MChunk::succ(int idx) const +{ + int i = (idx < low)? low : idx + 1; + while (i < fence && !valid(i)) ++i; + return i; +} + +inline int MChunk::pred(int idx) const +{ + int i = (idx > fence)? (fence - 1) : idx - 1; + while (i >= low && !valid(i)) --i; + return i; +} + +inline int MChunk::unused_indices() const +{ + return unused; +} + +inline * MChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + mark(fence); + return &(data[fence++ - base]); +} + +inline * MChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + mark(--low); + return &(data[low - base]); +} + +inline void MChunk::reset_low() +{ + while (low < fence && !valid(low)) + { + --unused; + ++low; + } +} + +inline void MChunk::reset_high() +{ + while (fence > low && !valid(fence - 1)) + { + --unused; + --fence; + } +} + +inline int MPlex::full () const +{ + return 0; +} + +inline int MPlex::can_add_high() const +{ + return 1; +} + +inline int MPlex::can_add_low() const +{ + return 1; +} + +inline int MPlex::available() const +{ + return unused; +} + +inline int MPlex::count() const +{ + return fnc - lo - unused; +} + +inline void MPlex::set_cache(const MChunk* t) const +{ + ((MPlex*)(this))->ch = (MChunk*)t; +} + +inline & MPlex:: operator [] (int idx) +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return * (ch->pointer_to(idx)); +} + +inline const & MPlex:: operator [] (int idx) const +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return * ((const *)(ch->pointer_to(idx))); +} + +inline int MPlex::Pix_to_index(Pix p) const +{ + if (!ch->MChunk::valid_pointer((*)p)) cache((*)p); + return ch->index_of((*)p); +} + +inline int MPlex::high() const +{ + return (((const MChunk*)tl())->MChunk::valid_index(fnc-1)) ? + fnc-1 : dopred(fnc-1); +} + +inline int MPlex::low() const +{ + return (((const MChunk*)hd)->MChunk::valid_index(lo))? lo : dosucc(lo); +} + +inline & MPlex::low_element () +{ + return (*this)[low()]; +} + +inline const & MPlex::low_element () const +{ + return (*this)[low()]; +} + +inline & MPlex::high_element () +{ + return (*this)[high()]; +} + +inline const & MPlex::high_element () const +{ + return (*this)[high()]; +} + +inline Pix MPlex::index_to_Pix(int idx) const +{ + if (!ch->MChunk::valid_index(idx)) cache(idx); + return Pix(ch->pointer_to(idx)); +} + +inline void MPlex::next(int& idx) const +{ + idx = (ch->MChunk::valid_index(idx+1))? idx+1 : dosucc(idx); +} + +inline void MPlex::prev(int& idx) const +{ + idx = (ch->MChunk::valid_index(idx-1))? idx-1 : dopred(idx); +} + +inline Pix MPlex::first() const +{ + return index_to_Pix(low()); +} + +inline Pix MPlex::last() const +{ + return index_to_Pix(high()); +} + + +inline void MPlex::undel_Pix(Pix p) +{ + undel_index(Pix_to_index(p)); +} + +inline int MPlex::del_Pix(Pix p) +{ + return del_index(Pix_to_index(p)); +} + +inline & MPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline const & MPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Map.ccP b/gnu/lib/libg++/g++-include/gen/Map.ccP new file mode 100644 index 0000000000..03bb4b84f0 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Map.ccP @@ -0,0 +1,58 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..Map.h" + + +Pix Map::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ(key(i), item)); next(i)); + return i; +} + +int Map::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void Map::clear() +{ + Pix i = first(); + while (i != 0) + { + del(key(i)); + i = first(); + } +} + +int Map::contains ( item) +{ + return seek(item) != 0; +} + + +void Map::error(const char* msg) +{ + (*lib_error_handler)("Map", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Map.hP b/gnu/lib/libg++/g++-include/gen/Map.hP new file mode 100644 index 0000000000..716a17fdd9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Map.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Map_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Map_h 1 + +#include +#include ".defs.h" + +class Map +{ +protected: + int count; + def; + +public: + Map( dflt); + virtual ~Map(); + + int length(); // current number of items + int empty(); + + virtual int contains( key); // is key mapped? + + virtual void clear(); // delete all items + + virtual & operator [] ( key) = 0; // access contents by key + + virtual void del( key) = 0; // delete entry + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & key(Pix i) = 0; // access key at i + virtual & contents(Pix i) = 0; // access contents at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( key); // Pix of key + + & dflt(); // access default val + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline Map::~Map() {} + +inline int Map::length() +{ + return count; +} + +inline int Map::empty() +{ + return count == 0; +} + +inline & Map::dflt() +{ + return def; +} + +inline Map::Map( dflt) :def(dflt) +{ + count = 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OSLBag.ccP b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP new file mode 100644 index 0000000000..78398192bc --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP @@ -0,0 +1,196 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OSLBag.h" + + +Pix OSLBag::seek( item, Pix i) +{ + if (i == 0) i = p.first(); else next(i); + for (; i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +int OSLBag::nof( item) +{ + int n = 0; + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + ++n; + else if (cmp < 0) + break; + } + return n; +} + +Pix OSLBag::add( item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLBag::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLBag::remove( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_front(); + i = p.first(); + } while (i != 0 && EQ(item, p(i))); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_after(trail); + i = trail; + next(i); + } while (i != 0 && EQ(item, p(i))); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +int OSLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= CMP(p(trail), p(i)) <= 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/OSLBag.hP b/gnu/lib/libg++/g++-include/gen/OSLBag.hP new file mode 100644 index 0000000000..de4d67cf9a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLBag.hP @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OSLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OSLBag_h 1 + +#include ".Bag.h" +#include ".SLList.h" + +class OSLBag : public Bag +{ +protected: + SLList p; + +public: + OSLBag(); + OSLBag(const OSLBag&); + + Pix add( item); + void del( item); + void remove(item); + + int contains( item); + int nof( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline OSLBag::OSLBag() : p() { count = 0; } + +inline OSLBag::OSLBag(const OSLBag& s) : p(s.p) { count = s.count; } + +inline Pix OSLBag::first() +{ + return p.first(); +} + +inline void OSLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & OSLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OSLBag::clear() +{ + count = 0; p.clear(); +} + +inline int OSLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OSLBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OSLSet.ccP b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP new file mode 100644 index 0000000000..bfd32ae954 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP @@ -0,0 +1,321 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OSLSet.h" + + +Pix OSLSet::seek( item) +{ + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +Pix OSLSet::add( item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void OSLSet::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + + +int OSLSet::operator <= (OSLSet& b) +{ + if (count > b.count) return 0; + Pix i = first(); + Pix j = b.first(); + for (;;) + { + if (i == 0) + return 1; + else if (j == 0) + return 0; + int cmp = CMP(p(i), b.p(j)); + if (cmp == 0) + { + next(i); b.next(j); + } + else if (cmp < 0) + return 0; + else + b.next(j); + } +} + +int OSLSet::operator == (OSLSet& b) +{ + if (count != b.count) return 0; + if (count == 0) return 1; + Pix i = p.first(); + Pix j = b.p.first(); + while (i != 0) + { + if (!EQ(p(i),b.p(j))) return 0; + next(i); + b.next(j); + } + return 1; +} + + +void OSLSet::operator |= (OSLSet& b) +{ + if (&b == this || b.count == 0) + return; + else + { + Pix j = b.p.first(); + Pix i = p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0) + return; + else if (i == 0) + { + for (; j != 0; b.next(j)) + { + ++count; + p.append(b.p(j)); + } + return; + } + int cmp = CMP(p(i), b.p(j)); + if (cmp <= 0) + { + if (cmp == 0) b.next(j); + trail = i; + next(i); + } + else + { + ++count; + if (trail == 0) + trail = p.prepend(b.p(j)); + else + trail = p.ins_after(trail, b.p(j)); + b.next(j); + } + } + } +} + + +void OSLSet::operator -= (OSLSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0 || i == 0) + return; + int cmp = CMP(p(i), b.p(j)); + if (cmp == 0) + { + --count; + b.next(j); + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else if (cmp < 0) + { + trail = i; + next(i); + } + else + b.next(j); + } + } +} + +void OSLSet::operator &= (OSLSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (i == 0) + return; + else if (j == 0) + { + if (trail == 0) + { + p.clear(); + count = 0; + } + else + { + while (i != 0) + { + --count; + next(i); + p.del_after(trail); + } + } + return; + } + int cmp = CMP(p(i), b.p(j)); + + if (cmp == 0) + { + trail = i; + next(i); + b.next(j); + } + else if (cmp < 0) + { + --count; + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else + b.next(j); + } + } +} + + +int OSLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= CMP(p(trail), p(i)) < 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OSLSet.hP b/gnu/lib/libg++/g++-include/gen/OSLSet.hP new file mode 100644 index 0000000000..bf3707f6c7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLSet.hP @@ -0,0 +1,101 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OSLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OSLSet_h 1 + +#include ".Set.h" +#include ".SLList.h" + +class OSLSet : public Set +{ +protected: + SLList p; + +public: + OSLSet(); + OSLSet(const OSLSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + void operator |= (OSLSet& b); + void operator -= (OSLSet& b); + void operator &= (OSLSet& b); + + int operator == (OSLSet& b); + int operator != (OSLSet& b); + int operator <= (OSLSet& b); + + int OK(); +}; + + +inline OSLSet::OSLSet() : p() { count = 0; } + +inline OSLSet::OSLSet(const OSLSet& s) : p(s.p) { count = s.count; } + +inline Pix OSLSet::first() +{ + return p.first(); +} + +inline void OSLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & OSLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OSLSet::clear() +{ + count = 0; p.clear(); +} + +inline int OSLSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int OSLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OSLSet::operator != (OSLSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OXPBag.ccP b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP new file mode 100644 index 0000000000..6619e25ea1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP @@ -0,0 +1,221 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OXPBag.h" + + +Pix OXPBag::seek( item, Pix i) +{ + if (i == 0) + { + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > p.low() && EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + int cmp = CMP(item, p(i)); + if (cmp == 0) + { + next(i); + return (EQ(item, p(i)))? i : 0; + } + else if (cmp < 0) + { + int ind = p.Pix_to_index(i); + int l = ind; + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + cmp = CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > ind && EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + else + return 0; +} + +int OXPBag::nof( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && EQ(item, p[l - 1])) --l; + while (h < p.high() && EQ(item, p[h + 1])) ++h; + return h - l + 1; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix OXPBag::add( item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = mid; + break; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.high() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void OXPBag::del( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +void OXPBag::remove( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && EQ(item, p[l - 1])) --l; + while (h < p.high() && EQ(item, p[h + 1])) ++h; + int n = h - l + 1; + count -= n; + if (p.high() - h < l - p.low()) + { + h = p.high() - n; + for (int i = l; i <= h; ++i) p[i] = p[i+n]; + while (n-- > 0) p.del_high(); + } + else + { + l = p.low() + n; + for (int i = h; i >= l; --i) p[i] = p[i-n]; + while (n-- > 0) p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int OXPBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= CMP(p[i], p[i+1]) <= 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OXPBag.hP b/gnu/lib/libg++/g++-include/gen/OXPBag.hP new file mode 100644 index 0000000000..128d4a20e4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPBag.hP @@ -0,0 +1,73 @@ +#ifndef _OXPBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OXPBag_h 1 + +#include ".Bag.h" +#include ".XPlex.h" + +class OXPBag : public Bag +{ +protected: + XPlex p; + +public: + OXPBag(int chunksize = DEFAULT_INITIAL_CAPACITY); + OXPBag(const OXPBag&); + + Pix add( item); + void del( item); +#undef remove + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline OXPBag::OXPBag(int chunksize) + : p(chunksize) { count = 0; } + +inline OXPBag::OXPBag(const OXPBag& s) : p(s.p) { count = s.count; } + +inline Pix OXPBag::first() +{ + return p.first(); +} + +inline void OXPBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & OXPBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OXPBag::clear() +{ + count = 0; p.clear(); +} + +inline int OXPBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OXPBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OXPSet.ccP b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP new file mode 100644 index 0000000000..1461195451 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP @@ -0,0 +1,280 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".OXPSet.h" + + +Pix OXPSet::seek( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix OXPSet::add( item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.fence() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void OXPSet::del( item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int OXPSet::operator <= (OXPSet& b) +{ + if (count > b.count) return 0; + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i >= p.fence()) + return 1; + else if (j >= b.p.fence()) + return 0; + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + return 0; + else + ++j; + } +} + +int OXPSet::operator == (OXPSet& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + int i = p.low(); + int j = b.p.low(); + while (n-- > 0) if (!EQ(p[i++], b.p[j++])) return 0; + return 1; +} + + +void OXPSet::operator |= (OXPSet& b) +{ + if (&b == this || b.count == 0) + return; + else if (b.count <= 2) // small b -- just add + for (Pix i = b.first(); i; b.next(i)) add(b(i)); + else + { + // strategy: merge into top of p, simultaneously killing old bottom + int oldfence = p.fence(); + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i == oldfence) + { + while (j < b.p.fence()) p.add_high(b.p[j++]); + break; + } + else if (j == b.p.fence()) + { + while (i++ < oldfence) + { + p.add_high(p.low_element()); + p.del_low(); + } + break; + } + int cmp = CMP(p[i], b.p[j]); + if (cmp <= 0) + { + ++i; + if (cmp == 0) ++j; + p.add_high(p.low_element()); + p.del_low(); + } + else + p.add_high(b.p[j++]); + } + count = p.length(); + } +} + + + +void OXPSet::operator -= (OXPSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence) + break; + else if (j >= b.p.fence()) + { + if (k != i) + while (i < oldfence) p[k++] = p[i++]; + else + k = oldfence; + break; + } + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; + } + else + j++; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +void OXPSet::operator &= (OXPSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence || j >= b.p.fence()) + break; + int cmp = CMP(p[i], b.p[j]); + if (cmp == 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; ++j; + } + else if (cmp < 0) + ++i; + else + ++j; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +int OXPSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= CMP(p[i], p[i+1]) < 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OXPSet.hP b/gnu/lib/libg++/g++-include/gen/OXPSet.hP new file mode 100644 index 0000000000..4e0c97712d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPSet.hP @@ -0,0 +1,102 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _OXPSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _OXPSet_h 1 + +#include ".Set.h" +#include ".XPlex.h" + +class OXPSet : public Set +{ +protected: + XPlex p; + +public: + OXPSet(int chunksize = DEFAULT_INITIAL_CAPACITY); + OXPSet(const OXPSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + void operator |= (OXPSet& b); + void operator -= (OXPSet& b); + void operator &= (OXPSet& b); + + int operator == (OXPSet& b); + int operator != (OXPSet& b); + int operator <= (OXPSet& b); + + int OK(); +}; + + +inline OXPSet::OXPSet(int chunksize) + : p(chunksize) { count = 0; } + +inline OXPSet::OXPSet(const OXPSet& s) : p(s.p) { count = s.count; } + +inline Pix OXPSet::first() +{ + return p.first(); +} + +inline void OXPSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & OXPSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void OXPSet::clear() +{ + count = 0; p.clear(); +} + +inline int OXPSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int OXPSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int OXPSet::operator != (OXPSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.ccP b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP new file mode 100644 index 0000000000..764b11c5cf --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".PHPQ.h" + +// +// This defines a Pairing Heap structure +// +// See ``The Pairing Heap: A New Form of Self-Adjusting Heap'' +// Fredman, Segdewick et al, +// Algorithmica (1986) 1:111-129 +// +// In particular, this implements the pairing heap using the circular +// list. +// +// + +PHPQ::PHPQ(int sz) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(sz); +} + +PHPQ::PHPQ(PHPQ& a) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(a.size); + for (Pix i = a.first(); i != 0; a.next(i)) enq(a(i)); +} + + +void PHPQ::prealloc(int newsize) +{ + ++newsize; // leave a spot for freelist + if (size != 0) + { + int news = size; + while (news <= newsize) news = (news * 3) / 2; + newsize = news; + } + // see if indices are OK + PHPQNode test; + test.sibling = 0; + test.sibling = ~test.sibling; + if ((unsigned long)newsize > (unsigned long)(test.sibling)) + error("storage size exceeds index range"); + + if (storage == 0) + { + storage = new PHPQNode[size = newsize]; + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + } + else + { + PHPQNode* newstor = new PHPQNode[newsize]; + for (int i = 1; i < size; ++i) + newstor[i] = storage[i]; + delete [] storage; + storage = newstor; + for (i = size; i < newsize; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[newsize-1].sibling = 0; + storage[0].sibling = size; + size = newsize; + } +} + + +void PHPQ::clear() +{ + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + root = 0; + count = 0; +} + +Pix PHPQ::enq( item) +{ + ++count; + if (storage[0].sibling == 0) + prealloc(count); + + int cell = storage[0].sibling; + storage[0].sibling = storage[cell].sibling; + storage[cell].sibling = 0; + storage[cell].children = 0; + storage[cell].item = item; + storage[cell].valid = 1; + + if (root == 0) + { + root = cell; + return Pix(root); + } + else + { + int parent; + int child; + + if (LE(storage[root].item, storage[cell].item)) + { + parent = root; child = cell; + } + else + { + parent = cell; child = root; + } + int popsKid = storage[parent].children; + + if (popsKid == 0) + { + storage[parent].children = child; + storage[child].sibling = child; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = child; + storage[child].sibling = temp; + storage[parent].children = child; + } + root = parent; + return Pix(cell); + } +} + +// +// Item removal is the most complicated routine. +// +// We remove the root (should there be one) and then select a new +// root. The siblings of the root are in a circular list. We continue +// to pair elements in this list until there is a single element. +// This element will be the new root. + +void PHPQ::del_front() +{ + int valid = 0; + do + { + if (root == 0) return; + if (valid = storage[root].valid) + --count; + storage[root].valid = 0; + int child = storage[root].children; + storage[root].sibling = storage[0].sibling; + storage[0].sibling = root; + + if (child == 0) + { + root = 0; + return; + } + else + { + while(storage[child].sibling != child) + { + // We have at least two kids, but we may only have + // two kids. So, oneChild != child, but it is possible + // that twoChild == child. + + int oneChild = storage[child].sibling; + int twoChild = storage[oneChild].sibling; + + // Remove the two from the sibling list + + storage[child].sibling = storage[twoChild].sibling; + storage[oneChild].sibling = 0; + storage[twoChild].sibling = 0; + + int bestChild; + int worstChild; + + if (LE(storage[oneChild].item, storage[twoChild].item)) + { + bestChild = oneChild; worstChild = twoChild; + } + else + { + bestChild = twoChild; worstChild = oneChild; + } + int popsKid = storage[bestChild].children; + + if (popsKid == 0) + { + storage[bestChild].children = worstChild; + storage[worstChild].sibling = worstChild; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = worstChild; + storage[worstChild].sibling = temp; + storage[bestChild].children = worstChild; + } + if (twoChild == child) + { + // We have reduced the two to one, so we'll be exiting. + child = bestChild; + storage[child].sibling = child; + } + else + { + // We've removed two siblings, now we need to insert + // the better of the two + storage[bestChild].sibling = storage[child].sibling; + storage[child].sibling = bestChild; + child = storage[bestChild].sibling; + } + } + root = child; + } + } while ( !valid ); +} + +void PHPQ::del(Pix p) +{ + if (p == 0) error("null Pix"); + int i = int(p); + if (storage[i].valid) + { + if (i == root) + del_front(); + else + { + storage[i].valid = 0; + --count; + } + } +} + + +Pix PHPQ::seek( key) +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid && EQ(storage[i].item, key)) + return Pix(i); + return 0; +} + +Pix PHPQ::first() +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid) + return Pix(i); + return 0; +} + + +void PHPQ::next(Pix& p) +{ + if (p == 0) return; + for (int i = int(p)+1; i < size; ++i) + if (storage[i].valid) + { + p = Pix(i); + return; + } + p = 0; +} + +int PHPQ::OK() +{ + int v = storage != 0; + int n = 0; + for (int i = 0; i < size; ++i) if (storage[i].valid) ++n; + v &= n == count; + v &= check_sibling_list(root); + int ct = MAXLONG; + n = 0; + int f = storage[0].sibling; + while (f != 0 && ct-- > 0) + { + f = storage[f].sibling; + ++n; + } + v &= ct > 0; + v &= n <= size - count; + if (!v) error("invariant failure"); + return v; +} + + +int PHPQ::check_sibling_list(int t) +{ + if (t != 0) + { + int s = t; + long ct = MAXLONG; // Lots of chances to find self! + do + { + if (storage[s].valid && !check_sibling_list(storage[s].children)) + return 0; + s = storage[s].sibling; + } while (ct-- > 0 && s != t && s != 0); + if (ct <= 0) return 0; + } + return 1; +} + + diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.hP b/gnu/lib/libg++/g++-include/gen/PHPQ.hP new file mode 100644 index 0000000000..359c527c60 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PHPQ.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef PHPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define PHPQ_h 1 + +#include ".PQ.h" + +#ifndef PHPQIndex +#define PHPQIndex unsigned short +#endif + +struct PHPQNode +{ + PHPQIndex sibling; + PHPQIndex children; + item; + char valid; +}; + + +class PHPQ : public PQ +{ + PHPQNode* storage; // table -- freelist in storage[0].sibling + int root; + int size; + + void prealloc(int); + int check_sibling_list(int); + +public: + + PHPQ(int sz = DEFAULT_INITIAL_CAPACITY); + PHPQ(PHPQ&); + ~PHPQ(); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + void del(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + + +inline PHPQ::~PHPQ() +{ + delete [] storage; +} + + +inline PHPQ::deq() +{ + if (count == 0) error("deq of empty PQ"); + x = storage[root].item; + del_front(); + return x; +} + + +inline & PHPQ::front() +{ + if (count == 0) error("front of empty PQ"); + return storage[root].item; +} + +inline int PHPQ::contains( item) +{ + return seek(item) != 0; +} + +inline & PHPQ::operator() (Pix p) +{ + if (p == 0) error("null Pix"); + return storage[int(p)].item; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PQ.ccP b/gnu/lib/libg++/g++-include/gen/PQ.ccP new file mode 100644 index 0000000000..810240759c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PQ.ccP @@ -0,0 +1,62 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".PQ.h" + + + + PQ::deq() +{ + x = front(); + del_front(); + return x; +} + +Pix PQ::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ((*this)(i), item)); next(i)); + return i; +} + +int PQ::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void PQ::clear() +{ + while (count != 0) del_front(); +} + +int PQ::contains ( item) +{ + return seek(item) != 0; +} + + +void PQ::error(const char* msg) +{ + (*lib_error_handler)("PQ", msg); +} + diff --git a/gnu/lib/libg++/g++-include/gen/PQ.hP b/gnu/lib/libg++/g++-include/gen/PQ.hP new file mode 100644 index 0000000000..981592ae85 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PQ.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _PQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _PQ_h 1 + +#include +#include ".defs.h" + +class PQ +{ +protected: + + int count; + +public: + PQ(); + virtual ~PQ(); + + int length(); // current number of items + int empty(); + + virtual Pix enq( item) = 0; // add item; return Pix + virtual deq(); // return & remove min + + virtual & front() = 0; // access min item + virtual void del_front() = 0; // delete min item + + virtual int contains( item); // is item in PQ? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & operator () (Pix i) = 0; // access item at i + virtual void del(Pix i) = 0; // delete item at i + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( item); // Pix of item + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline PQ::PQ() :count(0) {} + +inline PQ::~PQ() {} + +inline int PQ::length() +{ + return count; +} + +inline int PQ::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PSList.hP b/gnu/lib/libg++/g++-include/gen/PSList.hP new file mode 100644 index 0000000000..eacb34dbe3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PSList.hP @@ -0,0 +1,32 @@ +/* : Light weight list: This will simply reuse code from a VoidP List, which +was genclassed from the SLList libg++ class. The classes generated from this file +will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not +offer all the functionality of List classes, such as sharing of sub-lists. +However, no additional code is needed at all and no .cc file is generated. So it costs nothing +to use these type-safe lists. Only member functions needing type casting are re-defined */ + + +#ifndef _SList_h +#define _SList_h 1 + +#include "VoidP.SLList.h" +#include ".defs.h" + +class SList : public VoidPSLList +{ +public: + SList() {} + SList(SList& a) : (a) {} + ~SList() {} + + SList& operator = (SList& a) { + return (SList&) VoidPSLList::operator= (a); } + + & operator () (Pix p) { return (&) (VoidPSLList::operator() (p)); } + & front() { return (&) VoidPSLList::front(); } + & rear() { return (&) VoidPSLList::rear(); } + remove_front() { return () VoidPSLList::remove_front(); } + +}; + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/gen/PVec.hP b/gnu/lib/libg++/g++-include/gen/PVec.hP new file mode 100644 index 0000000000..de32482610 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PVec.hP @@ -0,0 +1,79 @@ +/* : light weight Vector: This will simply reuse code from */ +/* a VoidP Vec, which was genclassed from the Vec libg++ class. */ +/* The classes generated from this file will all be derived classes */ +/* from class VoidVec or intVec. No .cc file is generated. So */ +/* it costs nothing to use these type-safe Vectors. Only member */ +/* functions needing type casting are re-defined. */ +/* */ + +#ifndef _Vec_h +#define _Vec_h 1 + +#include "VoidP.Vec.h" +#include ".defs.h" + + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)( ); +typedef (*Mapper)( ); +typedef (*Combiner)( , ); +typedef int (*Predicate)( ); +typedef int (*Comparator)( , ); +#endif + +class Vec : public VoidPVec +{ +protected: + Vec(int l, * d) : (l, (VoidP*) d) {}; +public: + Vec() {}; + Vec(int l) : (l) {}; + Vec(int l, fill_value) : (l, fill_value) {}; + Vec(Vec& v) : (v) {}; + Vec(VoidPVec& v) {fake_copy(v, s, len);} + ~Vec() {}; + + Vec& operator = (Vec& a) + {return (Vec&) VoidPVec::operator= (a);} + Vec at(int from, int n) {return (Vec) VoidPVec::at(from, n);} + + & operator [] (int n) {return (&)VoidPVec::operator[] (n);} + & elem(int n) {return (&)VoidPVec::elem(n);} + + friend Vec concat(Vec& a, Vec& b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec& a); + + void sort(Comparator f); + void apply(Procedure f); + reduce(Combiner f, base); +}; + +inline Vec concat(Vec& a, Vec& b) +{return (Vec)concat((VoidPVec&)a, (VoidPVec&)b);} + +inline Vec map(Mapper f, Vec & a) { + return (Vec)map((VoidPMapper)f, (VoidPVec&)a); } + +inline Vec merge(Vec & a, Vec & b, Comparator f) { + return (Vec)merge((VoidPVec&)a, (VoidPVec&)b, (VoidPComparator)f); } + +inline Vec combine(Combiner f, Vec & a, Vec & b) { + return (Vec)combine((VoidPCombiner)f, (VoidPVec&)a, (VoidPVec&)b); } + +inline Vec reverse(Vec& a) { + return (Vec)reverse((VoidPVec&)a);} + +inline void Vec::sort(Comparator f) { + VoidPVec::sort((VoidPComparator) f); } + +inline void Vec::apply(Procedure f) { + VoidPVec::apply((VoidPProcedure) f); } + +inline Vec::reduce(Combiner f, base) { + return ()VoidPVec::reduce((VoidPCombiner)f, base);} + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/gen/Plex.ccP b/gnu/lib/libg++/g++-include/gen/Plex.ccP new file mode 100644 index 0000000000..5eb13c85f4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Plex.ccP @@ -0,0 +1,222 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".Plex.h" + +// IChunk support + +void IChunk::error(const char* msg) const +{ + (*lib_error_handler)("IChunk", msg); +} + +void IChunk::index_error() const +{ + error("attempt to use invalid index"); +} + +void IChunk::empty_error() const +{ + error("invalid use of empty chunk"); +} + +void IChunk::full_error() const +{ + error("attempt to extend chunk beyond bounds"); +} + +IChunk:: ~IChunk() {} + +IChunk::IChunk(* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) +{ + if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx) + error("inconsistent specification"); + data = d; + base = baseidx; + low = lowidx; + fence = fenceidx; + top = topidx; + nxt = prv = this; +} + +void IChunk:: re_index(int lo) +{ + int delta = lo - low; + base += delta; + low += delta; + fence += delta; + top += delta; +} + + +void IChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; +} + +void IChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; +} + +int IChunk:: OK() const +{ + int v = data != 0; // have some data + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= nxt->prv == this; // and links are OK + v &= prv->nxt == this; + if (!v) error("invariant failure"); + return(v); +} + + +// error handling + + +void Plex::error(const char* msg) const +{ + (*lib_error_handler)("Plex", msg); +} + +void Plex::index_error() const +{ + error("attempt to access invalid index"); +} + +void Plex::empty_error() const +{ + error("attempted operation on empty plex"); +} + +void Plex::full_error() const +{ + error("attempt to increase size of plex past limit"); +} + +// generic plex ops + +Plex:: ~Plex() +{ + invalidate(); +} + + +void Plex::append (const Plex& a) +{ + for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]); +} + +void Plex::prepend (const Plex& a) +{ + for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]); +} + +void Plex::reverse() +{ + tmp; + int l = low(); + int h = high(); + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + + +void Plex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void Plex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void Plex::del_chunk(IChunk* x) +{ + if (x != 0) + { + x->unlink(); + * data = (*)(x->invalidate()); + delete [] data; + delete x; + } +} + + +void Plex::invalidate() +{ + IChunk* t = hd; + if (t != 0) + { + IChunk* tail = tl(); + while (t != tail) + { + IChunk* nxt = t->next(); + del_chunk(t); + t = nxt; + } + del_chunk(t); + hd = 0; + } +} + +int Plex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + return old; +} + + + + diff --git a/gnu/lib/libg++/g++-include/gen/Plex.hP b/gnu/lib/libg++/g++-include/gen/Plex.hP new file mode 100644 index 0000000000..f8af1b6ba7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Plex.hP @@ -0,0 +1,494 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _Plex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Plex_h 1 + +#include +#include +#include ".defs.h" + +// Plexes are made out of IChunks + +#include + +class IChunk +{ +//public: // kludge until C++ `protected' policies settled +protected: + + * data; // data, from client + + int base; // lowest possible index + int low; // lowest valid index + int fence; // highest valid index + 1 + int top; // highest possible index + 1 + + IChunk* nxt; // circular links + IChunk* prv; + +public: + +// constructors + + IChunk(* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, + int fence_idx, + int top_idx); + + virtual ~IChunk(); + +// status reports + + int size() const; // number of slots + + virtual int empty() const ; + virtual int full() const ; + + int can_grow_high () const ; // there is space to add data + int can_grow_low () const; + + int base_index() const; // lowest possible index; + int low_index() const; // lowest actual index; + virtual int first_index() const; // lowest valid index or fence if none + virtual int last_index() const; // highest valid index or low-1 if none + int fence_index() const; // highest actual index + 1 + int top_index() const; // highest possible index + 1 + +// indexing conversion + + int possible_index(int i) const; // i between base and top + int actual_index(int i) const; // i between low and fence + virtual int valid_index(int i) const; // i not deleted (mainly for mchunks) + + int possible_pointer(const * p) const; // same for ptr + int actual_pointer(const * p) const; + virtual int valid_pointer(const * p) const; + + * pointer_to(int i) const ; // pointer to data indexed by i + // caution: i is not checked for validity + int index_of(const * p) const; // index of data pointed to by p + // caution: p is not checked for validity + + virtual int succ(int idx) const; // next valid index or fence if none + virtual int pred(int idx) const; // previous index or low - 1 if none + + virtual * first_pointer() const; // pointer to first valid pos or 0 + virtual * last_pointer() const; // pointer to first valid pos or 0 + virtual * succ(* p) const; // next pointer or 0 + virtual * pred(* p) const; // previous pointer or 0 + +// modification + + virtual * grow_high (); // return spot to add an element + virtual * grow_low (); + + virtual void shrink_high (); // logically delete top index + virtual void shrink_low (); + + virtual void clear(int lo); // reset to empty ch with base = lo + virtual void cleardown(int hi); // reset to empty ch with top = hi + void re_index(int lo); // re-index so lo is new low + +// chunk traversal + + IChunk* next() const; + IChunk* prev() const; + + void link_to_prev(IChunk* prev); + void link_to_next(IChunk* next); + void unlink(); + +// state checks + + * invalidate(); // mark self as invalid; return data + // for possible deletion + + virtual int OK() const; // representation invariant + + void error(const char*) const; + void empty_error() const; + void full_error() const; + void index_error() const; +}; + +// Plex is a partly `abstract' class: few of the virtuals +// are implemented at the Plex level, only in the subclasses + +class Plex +{ +protected: + + IChunk* hd; // a chunk holding the data + int lo; // lowest index + int fnc; // highest index + 1 + int csize; // size of the chunk + + void invalidate(); // mark so OK() is false + void del_chunk(IChunk*); // delete a chunk + + IChunk* tl() const; // last chunk; + int one_chunk() const; // true if hd == tl() + +public: + +// constructors, etc. + + Plex(); // no-op + + virtual ~Plex(); + + +// Access functions + + virtual & operator [] (int idx) = 0; // access by index; + virtual & operator () (Pix p) = 0; // access by Pix; + + virtual & high_element () = 0; // access high element + virtual & low_element () = 0; // access low element + +// read-only versions for const Plexes + + virtual const & operator [] (int idx) const = 0; // access by index; + virtual const & operator () (Pix p) const = 0; // access by Pix; + + virtual const & high_element () const = 0; // access high element + virtual const & low_element () const = 0; // access low element + + +// Index functions + + virtual int valid (int idx) const = 0; // idx is an OK index + + virtual int low() const = 0; // lowest index or fence if none + virtual int high() const = 0; // highest index or low-1 if none + + int ecnef() const; // low limit index (low-1) + int fence() const; // high limit index (high+1) + + virtual void prev(int& idx) const= 0; // set idx to preceding index + // caution: pred may be out of bounds + + virtual void next(int& idx) const = 0; // set to next index + // caution: succ may be out of bounds + + virtual Pix first() const = 0; // Pix to low element or 0 + virtual Pix last() const = 0; // Pix to high element or 0 + virtual void prev(Pix& pix) const = 0; // preceding pix or 0 + virtual void next(Pix& pix) const = 0; // next pix or 0 + virtual int owns(Pix p) const = 0; // p is an OK Pix + +// index<->Pix + + virtual int Pix_to_index(Pix p) const = 0; // get index via Pix + virtual Pix index_to_Pix(int idx) const = 0; // Pix via index + +// Growth + + virtual int add_high(const elem) =0;// add new element at high end + // return new high + + virtual int add_low(const elem) = 0; // add new low element, + // return new low + +// Shrinkage + + virtual int del_high() = 0; // remove the element at high end + // return new high + virtual int del_low() = 0; // delete low element, return new lo + + // caution: del_low/high + // does not necessarily + // immediately call ::~ + + +// operations on multiple elements + + virtual void fill(const x); // set all elements = x + virtual void fill(const x, int from, int to); // fill from to to + virtual void clear() = 0; // reset to zero-sized Plex + virtual int reset_low(int newlow); // change low index,return old + virtual void reverse(); // reverse in-place + virtual void append(const Plex& a); // concatenate a copy + virtual void prepend(const Plex& a); // prepend a copy + +// status + + virtual int can_add_high() const = 0; + virtual int can_add_low() const = 0; + + int length () const; // number of slots + + int empty () const; // is the plex empty? + virtual int full() const = 0; // it it full? + + int chunk_size() const; // report chunk size; + + virtual int OK() const = 0; // representation invariant + + void error(const char* msg) const; + void index_error() const; + void empty_error() const; + void full_error() const; +}; + + +// IChunk ops + +inline int IChunk:: size() const +{ + return top - base; +} + + +inline int IChunk:: base_index() const +{ + return base; +} + +inline int IChunk:: low_index() const +{ + return low; +} + +inline int IChunk:: fence_index() const +{ + return fence; +} + +inline int IChunk:: top_index() const +{ + return top; +} + +inline * IChunk:: pointer_to(int i) const +{ + return &(data[i-base]); +} + +inline int IChunk:: index_of(const * p) const +{ + return ((int)p - (int)data) / sizeof() + base; +} + +inline int IChunk:: possible_index(int i) const +{ + return i >= base && i < top; +} + +inline int IChunk:: possible_pointer(const * p) const +{ + return p >= data && p < &(data[top-base]); +} + +inline int IChunk:: actual_index(int i) const +{ + return i >= low && i < fence; +} + +inline int IChunk:: actual_pointer(const * p) const +{ + return p >= data && p < &(data[fence-base]); +} + +inline int IChunk:: can_grow_high () const +{ + return fence < top; +} + +inline int IChunk:: can_grow_low () const +{ + return base < low; +} + +inline * IChunk:: invalidate() +{ + * p = data; + data = 0; + return p; +} + + +inline IChunk* IChunk::prev() const +{ + return prv; +} + +inline IChunk* IChunk::next() const +{ + return nxt; +} + +inline void IChunk::link_to_prev(IChunk* prev) +{ + nxt = prev->nxt; + prv = prev; + nxt->prv = this; + prv->nxt = this; +} + +inline void IChunk::link_to_next(IChunk* next) +{ + prv = next->prv; + nxt = next; + nxt->prv = this; + prv->nxt = this; +} + +inline void IChunk::unlink() +{ + IChunk* n = nxt; + IChunk* p = prv; + n->prv = p; + p->nxt = n; + prv = nxt = this; +} + +inline int IChunk:: empty() const +{ + return low == fence; +} + +inline int IChunk:: full() const +{ + return top - base == fence - low; +} + +inline int IChunk:: first_index() const +{ + return (low == fence)? fence : low; +} + +inline int IChunk:: last_index() const +{ + return (low == fence)? low - 1 : fence - 1; +} + +inline int IChunk:: succ(int i) const +{ + return (i < low) ? low : i + 1; +} + +inline int IChunk:: pred(int i) const +{ + return (i > fence) ? (fence - 1) : i - 1; +} + +inline int IChunk:: valid_index(int i) const +{ + return i >= low && i < fence; +} + +inline int IChunk:: valid_pointer(const * p) const +{ + return p >= &(data[low - base]) && p < &(data[fence - base]); +} + +inline * IChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + return &(data[fence++ - base]); +} + +inline * IChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + return &(data[--low - base]); +} + +inline void IChunk:: shrink_high () +{ + if (empty()) empty_error(); + --fence; +} + +inline void IChunk:: shrink_low () +{ + if (empty()) empty_error(); + ++low; +} + +inline * IChunk::first_pointer() const +{ + return (low == fence)? 0 : &(data[low - base]); +} + +inline * IChunk::last_pointer() const +{ + return (low == fence)? 0 : &(data[fence - base - 1]); +} + +inline * IChunk::succ(* p) const +{ + return ((p+1) < &(data[low - base]) || (p+1) >= &(data[fence - base])) ? + 0 : (p+1); +} + +inline * IChunk::pred(* p) const +{ + return ((p-1) < &(data[low - base]) || (p-1) >= &(data[fence - base])) ? + 0 : (p-1); +} + + +// generic Plex operations + +inline Plex::Plex() {} + +inline int Plex::chunk_size() const +{ + return csize; +} + +inline int Plex::ecnef () const +{ + return lo - 1; +} + + +inline int Plex::fence () const +{ + return fnc; +} + +inline int Plex::length () const +{ + return fnc - lo; +} + +inline int Plex::empty () const +{ + return fnc == lo; +} + +inline IChunk* Plex::tl() const +{ + return hd->prev(); +} + +inline int Plex::one_chunk() const +{ + return hd == hd->prev(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Queue.ccP b/gnu/lib/libg++/g++-include/gen/Queue.ccP new file mode 100644 index 0000000000..fb48d952ff --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Queue.ccP @@ -0,0 +1,14 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Queue.h" + +Queue::~Queue() {} + + +// error handling + +void Queue::error(const char* msg) +{ + (*lib_error_handler)("Queue", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Queue.hP b/gnu/lib/libg++/g++-include/gen/Queue.hP new file mode 100644 index 0000000000..73db6e034e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Queue.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Queue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Queue_h + +#include + +#include ".defs.h" + +class Queue +{ +public: + Queue() { } + virtual ~Queue(); + + virtual void enq( item) = 0; + virtual deq() = 0; + virtual & front() = 0; + virtual void del_front() = 0; + + virtual void clear() = 0; + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + void error(const char*); + + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP new file mode 100644 index 0000000000..7537dd0788 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP @@ -0,0 +1,690 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..RAVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(RAVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(RAVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(RAVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(RAVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(RAVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(RAVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +RAVLNode* RAVLMap::leftmost() +{ + RAVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +RAVLNode* RAVLMap::rightmost() +{ + RAVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +RAVLNode* RAVLMap::succ(RAVLNode* t) +{ + RAVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +RAVLNode* RAVLMap::pred(RAVLNode* t) +{ + RAVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix RAVLMap::seek( key) +{ + RAVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +int RAVLMap::rankof( key) +{ + int r; + RAVLNode* t = root; + if (t == 0) + return 0; + for (r=t->rank; t != 0; r+=t->rank) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + return r; + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + { + r -= t->rank; + t = t->lt; + } + } + else if (rthread(t)) + return 0; + else + { + t = t->rt; + } + } + return 0; +} + +Pix RAVLMap::ranktoPix(int i) +{ + int r; + RAVLNode* t = root; + + if ((i<1)||(i>count)) + return 0; + for (r=t->rank; r!=i; r+=t->rank) + { + if (r>i) + { + r -= t->rank; + t = t->lt; + } + else + t = t->rt; + } + return Pix(t); +} + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static * _target_item; // add/del_item target +static RAVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases +static int _rank_changed; // for rank computation + + +void RAVLMap:: _add(RAVLNode*& t) +{ + int cmp = CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new RAVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->lt); + if (_rank_changed) ++t->rank; + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new RAVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +& RAVLMap::operator [] ( item) +{ + if (root == 0) + { + ++count; + root = new RAVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _rank_changed = 0; + _add(root); + return _found_node->cont; + } +} + + +void RAVLMap::_del(RAVLNode* par, RAVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + RAVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + RAVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else // replace item & find someone deletable + { + RAVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (_rank_changed) --t->rank; + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + RAVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + +void RAVLMap::del( item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _rank_changed = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void RAVLMap::_kill(RAVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +RAVLMap::RAVLMap(RAVLMap& b) :Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int RAVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + RAVLNode* trail = leftmost(); + v &= rankof(trail->item) == n; + RAVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + v &= rankof(t->item) == n; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/RAVLMap.hP b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP new file mode 100644 index 0000000000..d3c523ee29 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP @@ -0,0 +1,147 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + ranking code from Paul Anderson (paul%lfcs.ed.ac.uk) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _RAVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _RAVLMap_h 1 + +#include "..Map.h" + +struct RAVLNode +{ + RAVLNode* lt; + RAVLNode* rt; + item; + cont; + int rank; + char stat; + RAVLNode( h, c, + RAVLNode* l=0, RAVLNode* r=0, int k=1); + ~RAVLNode(); +}; + +inline RAVLNode::RAVLNode( h, c, + RAVLNode* l, RAVLNode* r, int k) + :item(h), cont(c), lt(l), rt(r), rank(k), stat(0) {} + +inline RAVLNode::~RAVLNode() {} + +typedef RAVLNode* RAVLNodePtr; + + +class RAVLMap : public Map +{ +protected: + RAVLNode* root; + + RAVLNode* leftmost(); + RAVLNode* rightmost(); + RAVLNode* pred(RAVLNode* t); + RAVLNode* succ(RAVLNode* t); + void _kill(RAVLNode* t); + void _add(RAVLNode*& t); + void _del(RAVLNode* p, RAVLNode*& t); + +public: + RAVLMap( dflt); + RAVLMap(RAVLMap& a); + ~RAVLMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + Pix ranktoPix(int i); + int rankof( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline RAVLMap::~RAVLMap() +{ + _kill(root); +} + +inline RAVLMap::RAVLMap( dflt) :Map(dflt) +{ + root = 0; +} + + +inline Pix RAVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix RAVLMap::last() +{ + return Pix(rightmost()); +} + +inline void RAVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((RAVLNode*)i)); +} + +inline void RAVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((RAVLNode*)i)); +} + +inline & RAVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((RAVLNode*)i)->item; +} + +inline & RAVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((RAVLNode*)i)->cont; +} + +inline void RAVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int RAVLMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/RPlex.ccP b/gnu/lib/libg++/g++-include/gen/RPlex.ccP new file mode 100644 index 0000000000..0dbd2cee7e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RPlex.ccP @@ -0,0 +1,477 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".RPlex.h" + +typedef IChunk* _IChunk_ptr; + +RPlex:: RPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +RPlex:: RPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize+lo)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + + +RPlex:: RPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +void RPlex::make_initial_chunks(int up) +{ + int count = 0; + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + set_cache((IChunk*)hd); + + maxch = MIN_NCHUNKS; + if (maxch < count * 2) + maxch = count * 2; + chunks = new _IChunk_ptr[maxch]; + lch = maxch / 3; + fch = lch + count; + base = ch->base_index() - csize * lch; + int k = lch; + do + { + chunks[k++] = ch; + set_cache(ch->next()); + } while (ch != hd); +} + +RPlex:: RPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + fill(initval); +} + +RPlex::RPlex(const RPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void RPlex::operator= (const RPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void RPlex::cache(const * p) const +{ + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) index_error(); + } + set_cache(t); +} + +int RPlex::owns(Pix px) const +{ + * p = (*)px; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + set_cache(t); + return 1; +} + + +* RPlex::dosucc(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + int i = t->index_of(p) + 1; + if (i >= fnc) return 0; + if (i >= t->fence_index()) t = (t->next()); + set_cache(t); + return t->pointer_to(i); +} + +* RPlex::dopred(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->prev()); + if (t == old) return 0; + } + int i = t->index_of(p) - 1; + if (i < lo) return 0; + if (i < t->low_index()) t = (t->prev()); + set_cache(t); + return (t->pointer_to(i)); +} + +int RPlex::add_high(const elem) +{ + IChunk* t = tl(); + if (!t->can_grow_high()) + { + if (t->IChunk::empty() && one_chunk()) + { + t->clear(fnc); + base = t->base_index() - lch * csize; + } + else + { + * data = new [csize]; + t = (new IChunk(data, fnc, fnc, fnc,fnc+csize)); + t->link_to_prev(tl()); + if (fch == maxch) + { + maxch *= 2; + IChunk** newch = new _IChunk_ptr [maxch]; + memcpy(newch, chunks, fch * sizeof(_IChunk_ptr)); + delete chunks; + chunks = newch; + } + chunks[fch++] = t; + } + } + *((t->IChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int RPlex::del_high () +{ + if (empty()) empty_error(); + IChunk* t = tl(); + if (t->IChunk::empty()) // kill straggler first + { + IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + t->IChunk::shrink_high(); + if (t->IChunk::empty() && !one_chunk()) + { + IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + set_cache(t); + return --fnc - 1; +} + +int RPlex::add_low (const elem) +{ + IChunk* t = hd; + if (!t->can_grow_low()) + { + if (t->IChunk::empty() && one_chunk()) + { + t->cleardown(lo); + base = t->base_index() - lch * csize; + } + else + { + * data = new [csize]; + hd = new IChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ( hd); + if (lch == 0) + { + lch = maxch; + fch += maxch; + maxch *= 2; + IChunk** newch = new _IChunk_ptr [maxch]; + memcpy(&(newch[lch]), chunks, lch * sizeof(_IChunk_ptr)); + delete chunks; + chunks = newch; + base = t->base_index() - (lch - 1) * csize; + } + chunks[--lch] = t; + } + } + *((t->IChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + + +int RPlex::del_low () +{ + if (empty()) empty_error(); + IChunk* t = hd; + if (t->IChunk::empty()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + t->IChunk::shrink_low(); + if (t->IChunk::empty() && !one_chunk()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + set_cache(t); + return ++lo; +} + +void RPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + IChunk* loch = hd; + IChunk* hich = tl(); + while (l < h) + { + * lptr = loch->pointer_to(l); + * hptr = hich->pointer_to(h); + tmp = *lptr; + *lptr = *hptr; + *hptr = tmp; + if (++l >= loch->fence_index()) loch = loch->next(); + if (--h < hich->low_index()) hich = hich->prev(); + } +} + +void RPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void RPlex::fill(const x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void RPlex::clear() +{ + for (int i = lch + 1; i < fch; ++i) + del_chunk(chunks[i]); + fch = lch + 1; + set_cache(chunks[lch]); + ch->IChunk::clear(lo); + fnc = lo; +} + +int RPlex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + base = hd->base_index() - lch * csize; + return old; +} + + +int RPlex::OK () const +{ + int v = hd != 0 && ch != 0; // at least one chunk + + v &= fnc == tl()->fence_index(); // last chunk fnc == plex fnc + v &= lo == hd->IChunk::low_index(); // first lo == plex lo + + v &= base == hd->base_index() - lch * csize; // base is correct; + v &= lch < fch; + v &= fch <= maxch; // within allocation; + +// loop for others: + + int k = lch; // to cross-check nch + + int found_ch = 0; // to make sure ch is in list; + const IChunk* t = (hd); + for (;;) + { + v &= chunks[k++] == t; // each chunk is at proper index + if (t == ch) ++found_ch; + v &= t->IChunk::OK(); // each chunk is OK + if (t == tl()) + break; + else // and has indices contiguous to succ + { + v &= t->top_index() == t->next()->base_index(); + if (t != hd) // internal chunks full + { + v &= !t->empty(); + v &= !t->can_grow_low(); + v &= !t->can_grow_high(); + } + t = t->next(); + } + } + v &= found_ch == 1; + v &= fch == k; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/RPlex.hP b/gnu/lib/libg++/g++-include/gen/RPlex.hP new file mode 100644 index 0000000000..ed28c357e4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RPlex.hP @@ -0,0 +1,257 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _RPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _RPlex_h 1 + +#include ".Plex.h" + +// minimum number of chunks to index + +#ifndef MIN_NCHUNKS +#define MIN_NCHUNKS 16 +#endif + +class RPlex: public Plex +{ + int base; // base index of lowest chunk + int lch; // index of lowest used chunk + int fch; // 1 + index of highest used chunk + int maxch; // max chunks in array + IChunk** chunks; // array of chunks + IChunk* ch; // cached chunk + + void make_initial_chunks(int up = 1); + + void cache(int idx) const; + void cache(const * p) const; + * dopred(const * p) const; + * dosucc(const * p) const; + + void set_cache(const IChunk* t) const; // logically, + // not physically const + +public: + RPlex(); // set low = 0; + // fence = 0; + // csize = default + + RPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + RPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + RPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + RPlex(const RPlex&); + + ~RPlex(); + + void operator= (const RPlex&); + +// virtuals + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int reset_low(int newlow); + + int OK () const; +}; + + +inline void RPlex::prev(int& idx) const +{ + --idx; +} + +inline void RPlex::next(int& idx) const +{ + ++idx; +} + +inline int RPlex::full () const +{ + return 0; +} + +inline int RPlex::can_add_high() const +{ + return 1; +} + +inline int RPlex::can_add_low() const +{ + return 1; +} + +inline int RPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int RPlex::low() const +{ + return lo; +} + +inline int RPlex::high() const +{ + return fnc - 1; +} + +inline void RPlex::set_cache(const IChunk* t) const +{ + ((RPlex*)(this))->ch = (IChunk*)t; +} + +inline void RPlex::cache(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + set_cache(chunks[(idx - base) / csize]); +} + +inline & RPlex::low_element () +{ + cache(lo); return *(ch->pointer_to(lo)); +} + +inline & RPlex::high_element () +{ + cache(fnc-1); return *(ch->pointer_to(fnc - 1)); +} + +inline const & RPlex::low_element () const +{ + cache(lo); return *((const *)(ch->pointer_to(lo))); +} + +inline const & RPlex::high_element () const +{ + cache(fnc-1); return *((const *)(ch->pointer_to(fnc - 1))); +} + +inline int RPlex::Pix_to_index(Pix px) const +{ + * p = (*)px; + if (!ch->actual_pointer(p)) cache(p); + return ch->index_of(p); +} + +inline Pix RPlex::index_to_Pix(int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return (Pix)(ch->pointer_to(idx)); +} + +inline Pix RPlex::first() const +{ + return Pix(hd->IChunk::first_pointer()); +} + +inline Pix RPlex::last() const +{ + return Pix(tl()->IChunk::last_pointer()); +} + +inline void RPlex::prev(Pix& p) const +{ + Pix q = Pix(ch->IChunk::pred((*)p)); + p = (q == 0)? Pix(dopred((*)p)) : q; +} + +inline void RPlex::next(Pix& p) const +{ + Pix q = Pix(ch->IChunk::succ((*)p)); + p = (q == 0)? Pix(dosucc((*)p)) : q; +} + +inline & RPlex:: operator () (Pix p) +{ + return *((*)p); +} + + +inline & RPlex:: operator [] (int idx) +{ + cache(idx); return *(ch->pointer_to(idx)); +} + +inline const & RPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline const & RPlex:: operator [] (int idx) const +{ + cache(idx); return *((const *)(ch->pointer_to(idx))); +} + +inline RPlex::~RPlex() +{ + delete chunks; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLBag.ccP b/gnu/lib/libg++/g++-include/gen/SLBag.ccP new file mode 100644 index 0000000000..50d2447c7d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLBag.ccP @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLBag.h" + +int SLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix SLBag::seek( item, Pix i) +{ + if (i == 0) i = first(); else next(i); + for (; i != 0 && (!(EQ(p(i), item))); p.next(i)); + return i; +} + +int SLBag::nof( item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (EQ((*this)(p), item)) ++n; + return n; +} + + +void SLBag::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + +void SLBag::remove( item) +{ + Pix i = p.first(); + while (i != 0 && EQ(p(i), item)) + { + --count; + p.del_front(); + i = p.first(); + } + if (i != 0) + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + i = trail; + p.next(i); + } + else + { + trail = i; + p.next(i); + } + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/SLBag.hP b/gnu/lib/libg++/g++-include/gen/SLBag.hP new file mode 100644 index 0000000000..edb648e9d3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLBag.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLBag_h 1 + +#include ".Bag.h" +#include ".SLList.h" + +class SLBag : public Bag +{ +protected: + SLList p; + +public: + SLBag(); + SLBag(const SLBag&); + + Pix add( item); + void del( item); + void remove(item); + int contains( item); + int nof( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline SLBag::SLBag() : p() { count = 0; } + +inline SLBag::SLBag(const SLBag& s) : p(s.p) { count = s.count; } + +inline Pix SLBag::first() +{ + return p.first(); +} + +inline void SLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & SLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void SLBag::clear() +{ + count = 0; p.clear(); +} + +inline int SLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline Pix SLBag::add( item) +{ + ++count; + return p.append(item); +} + +inline int SLBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLList.ccP b/gnu/lib/libg++/g++-include/gen/SLList.ccP new file mode 100644 index 0000000000..3ebd8d5bc9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLList.ccP @@ -0,0 +1,292 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include +#include ".SLList.h" + +void SLList::error(const char* msg) +{ + (*lib_error_handler)("SLList", msg); +} + +int SLList::length() +{ + int l = 0; + SLListNode* t = last; + if (t != 0) do { ++l; t = t->tl; } while (t != last); + return l; +} + +SLList::SLList(const SLList& a) +{ + if (a.last == 0) + last = 0; + else + { + SLListNode* p = a.last->tl; + SLListNode* h = new SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + return; + } + p = p->tl; + SLListNode* n = new SLListNode(p->hd); + last->tl = n; + last = n; + } + } +} + +SLList& SLList::operator = (const SLList& a) +{ + if (last != a.last) + { + clear(); + if (a.last != 0) + { + SLListNode* p = a.last->tl; + SLListNode* h = new SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + break; + } + p = p->tl; + SLListNode* n = new SLListNode(p->hd); + last->tl = n; + last = n; + } + } + } + return *this; +} + +void SLList::clear() +{ + if (last == 0) + return; + + SLListNode* p = last->tl; + last->tl = 0; + last = 0; + + while (p != 0) + { + SLListNode* nxt = p->tl; + delete(p); + p = nxt; + } +} + + +Pix SLList::prepend( item) +{ + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix SLList::prepend(SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix SLList::append( item) +{ + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +Pix SLList::append(SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +void SLList::join(SLList& b) +{ + SLListNode* t = b.last; + b.last = 0; + if (last == 0) + last = t; + else if (t != 0) + { + SLListNode* f = last->tl; + last->tl = t->tl; + t->tl = f; + last = t; + } +} + +Pix SLList::ins_after(Pix p, item) +{ + SLListNode* u = (SLListNode*)p; + SLListNode* t = new SLListNode(item); + if (last == 0) + t->tl = last = t; + else if (u == 0) // ins_after 0 means prepend + { + t->tl = last->tl; + last->tl = t; + } + else + { + t->tl = u->tl; + u->tl = t; + if (u == last) + last = t; + } + return Pix(t); +} + + +void SLList::del_after(Pix p) +{ + SLListNode* u = (SLListNode*)p; + if (last == 0 || u == last) error("cannot del_after last"); + if (u == 0) u = last; // del_after 0 means delete first + SLListNode* t = u->tl; + if (u == t) + last = 0; + else + { + u->tl = t->tl; + if (last == t) + last = u; + } + delete t; +} + +int SLList::owns(Pix p) +{ + SLListNode* t = last; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->tl; + } while (t != last); + } + return 0; +} + + SLList::remove_front() +{ + if (last == 0) error("remove_front of empty list"); + SLListNode* t = last->tl; + res = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return res; +} + +int SLList::remove_front(& x) +{ + if (last == 0) + return 0; + else + { + SLListNode* t = last->tl; + x = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return 1; + } +} + + +void SLList::del_front() +{ + if (last == 0) error("del_front of empty list"); + SLListNode* t = last->tl; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; +} + +int SLList::OK() +{ + int v = 1; + if (last != 0) + { + SLListNode* t = last; + long count = MAXLONG; // Lots of chances to find last! + do + { + count--; + t = t->tl; + } while (count > 0 && t != last); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SLList.hP b/gnu/lib/libg++/g++-include/gen/SLList.hP new file mode 100644 index 0000000000..e5570bdf8f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLList.hP @@ -0,0 +1,137 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLList_h 1 + +#include +#include ".defs.h" + +#ifndef _SLListNode_h +#define _SLListNode_h 1 + +struct SLListNode +{ + SLListNode* tl; + hd; + SLListNode() { } + SLListNode(const h, SLListNode* t = 0); + ~SLListNode() { } +}; + + +inline SLListNode::SLListNode(const h, SLListNode* t) +:hd(h), tl(t) {} + +typedef SLListNode* SLListNodePtr; + +#endif + + +class SLList +{ +protected: + SLListNode* last; + +public: + SLList(); + SLList(const SLList& a); + ~SLList(); + + SLList& operator = (const SLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend( item); + Pix append( item); + + void join(SLList&); + + Pix prepend(SLListNode*); + Pix append(SLListNode*); + + & operator () (Pix p); + Pix first(); + void next(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, item); + void del_after(Pix p); + + & front(); + & rear(); + remove_front(); + int remove_front(& x); + void del_front(); + + void error(const char* msg); + int OK(); +}; + +inline SLList::~SLList() +{ + clear(); +} + +inline SLList::SLList() +{ + last = 0; +} + +inline int SLList::empty() +{ + return last == 0; +} + + +inline Pix SLList::first() +{ + return (last == 0)? 0 : Pix(last->tl); +} + +inline void SLList::next(Pix& p) +{ + p = (p == 0 || p == last)? 0 : Pix(((SLListNode*)(p))->tl); +} + +inline & SLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((SLListNode*)(p))->hd; +} + +inline & SLList::front() +{ + if (last == 0) error("front: empty list"); + return last->tl->hd; +} + +inline & SLList::rear() +{ + if (last == 0) error("rear: empty list"); + return last->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.ccP b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP new file mode 100644 index 0000000000..8a5935b775 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLQueue.h" diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.hP b/gnu/lib/libg++/g++-include/gen/SLQueue.hP new file mode 100644 index 0000000000..20fd74c9c5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLQueue.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _SLQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLQueue_h + +#include ".SLList.h" +#include ".Queue.h" + +class SLQueue : public Queue +{ + SLList p; + +public: + SLQueue(); + SLQueue(const SLQueue& q); + ~SLQueue(); + + void operator = (const SLQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline SLQueue::SLQueue() :p() {} +inline SLQueue::SLQueue(const SLQueue& q) : p(q.p) {} + +inline SLQueue::~SLQueue() {} + +inline void SLQueue::enq(item) +{ + p.append(item); +} + +inline SLQueue::deq() +{ + return p.remove_front(); +} + +inline & SLQueue::front() +{ + return p.front(); +} + + +inline void SLQueue::del_front() +{ + p.del_front(); +} + +inline void SLQueue::operator =(const SLQueue& s) +{ + p = s.p; +} + +inline int SLQueue::empty() +{ + return p.empty(); +} + +inline int SLQueue::full() +{ + return 0; +} + +inline int SLQueue::length() +{ + return p.length(); +} + +inline int SLQueue::OK() +{ + return p.OK(); +} + +inline void SLQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLSet.ccP b/gnu/lib/libg++/g++-include/gen/SLSet.ccP new file mode 100644 index 0000000000..5f580849ff --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLSet.ccP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLSet.h" + +int SLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix SLSet::seek( item) +{ + for (Pix i = p.first(); i != 0 && !EQ(p(i),item); p.next(i)); + return i; +} + +Pix SLSet::add( item) +{ + Pix i = seek(item); + if (i == 0) + { + ++count; + i = p.append(item); + } + return i; +} + +void SLSet::del( item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/SLSet.hP b/gnu/lib/libg++/g++-include/gen/SLSet.hP new file mode 100644 index 0000000000..fcf153633f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLSet.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLSet_h 1 + +#include ".Set.h" +#include ".SLList.h" + +class SLSet : public Set +{ +protected: + SLList p; + +public: + SLSet(); + SLSet(const SLSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); +}; + +inline SLSet::SLSet() : p() { count = 0; } + +inline SLSet::SLSet(const SLSet& s) : p(s.p) { count = s.count; } + +inline Pix SLSet::first() +{ + return p.first(); +} + +inline void SLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & SLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void SLSet::clear() +{ + count = 0; p.clear(); +} + +inline int SLSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int SLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.ccP b/gnu/lib/libg++/g++-include/gen/SLStack.ccP new file mode 100644 index 0000000000..3996b41fac --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SLStack.h" diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.hP b/gnu/lib/libg++/g++-include/gen/SLStack.hP new file mode 100644 index 0000000000..e20d9b9c2a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLStack.hP @@ -0,0 +1,109 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SLStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SLStack_h 1 + +#include ".SLList.h" +#include ".Stack.h" + +class SLStack : public Stack +{ + SLList p; + +public: + SLStack(); + SLStack(const SLStack& s); + ~SLStack(); + + void operator = (const SLStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + +inline SLStack::SLStack() :p() {} +inline SLStack::SLStack(const SLStack& a) : p(a.p) {} +inline SLStack::~SLStack() {} + +inline void SLStack::push( item) +{ + p.prepend(item); +} + +inline SLStack::pop() +{ + return p.remove_front(); +} + +inline & SLStack::top() +{ + return p.front(); +} + +inline void SLStack::del_top() +{ + p.del_front(); +} + +inline void SLStack::operator =(const SLStack& s) +{ + p = s.p; +} + +inline int SLStack::empty() +{ + return p.empty(); +} + +inline int SLStack::full() +{ + return 0; +} + +inline int SLStack::length() +{ + return p.length(); +} + +inline int SLStack::OK() +{ + return p.OK(); +} + +inline void SLStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Set.ccP b/gnu/lib/libg++/g++-include/gen/Set.ccP new file mode 100644 index 0000000000..f312aa15cc --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Set.ccP @@ -0,0 +1,116 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".Set.h" + + +Pix Set::seek( item) +{ + for (Pix i = first(); i != 0 && !(EQ((*this)(i), item)); next(i)); + return i; +} + +int Set::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void Set::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + +int Set::contains ( item) +{ + return seek(item) != 0; +} + +int Set::operator <= (Set& b) +{ + if (count > b.count) return 0; + if (count == 0) return 1; + for (Pix i = first(); i; next(i)) if (b.seek((*this)(i)) == 0) return 0; + return 1; +} + +int Set::operator == (Set& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + Pix i = first(); + Pix j = b.first(); + while (n-- > 0) + { + if ((b.seek((*this)(i)) == 0) || (seek(b(j)) == 0)) return 0; + next(i); + b.next(j); + } + return 1; +} + +int Set::operator != (Set& b) +{ + return !(*this == b); +} + +void Set::operator |= (Set& b) +{ + if (&b != this) + for (Pix i = b.first(); i; b.next(i)) add(b(i)); +} + +void Set::operator -= (Set& b) +{ + if (&b == this) + clear(); + else + for (Pix i = b.first(); i; b.next(i)) del(b(i)); +} + + +void Set::operator &= (Set& b) +{ + if (&b != this) + { + Pix i = first(); + Pix n = i; + while (i != 0) + { + next(n); + if (b.seek((*this)(i)) == 0) del((*this)(i)); + i = n; + } + } +} + +void Set::error(const char* msg) +{ + (*lib_error_handler)("Set", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Set.hP b/gnu/lib/libg++/g++-include/gen/Set.hP new file mode 100644 index 0000000000..6c21922627 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Set.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Set_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Set_h 1 + +#include +#include ".defs.h" + +class Set +{ +protected: + + int count; + +public: + virtual ~Set(); + + int length(); // current number of items + int empty(); + + virtual Pix add( item) = 0; // add item; return Pix + virtual void del( item) = 0; // delete item + virtual int contains( item); // is item in set? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual & operator () (Pix i) = 0; // access item at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek( item); // Pix of item + + void operator |= (Set& b); // add all items in b + void operator -= (Set& b); // delete items also in b + void operator &= (Set& b); // delete items not in b + + int operator == (Set& b); + int operator != (Set& b); + int operator <= (Set& b); + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline Set::~Set() {} + +inline int Set::length() +{ + return count; +} + +inline int Set::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipBag.ccP b/gnu/lib/libg++/g++-include/gen/SkipBag.ccP new file mode 100644 index 0000000000..cc347e9813 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipBag.ccP @@ -0,0 +1,322 @@ +// This may look like C code, but it is really -*- C++ -*- + +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include +#include +#include ".SkipBag.h" + +MLCG* SkipBag::gen = 0; +int SkipBaginit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +SkipBag::SkipBag(long size) +: level(0), + header(new SkipBagNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipBagNodePtr) header; +} + +SkipBag::SkipBag(SkipBag& b) +: level (0), + header (new SkipBagNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipBagNodePtr)header; + + for (SkipBagNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +Pix SkipBag::add ( item) +{ + SkipBagNodePtr *update = new SkipBagNodePtr[max_levels+1]; + SkipBagNodePtr curr = (SkipBagNodePtr) this->header; + int l = level; + SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipBagNodePtr)header; + }; + + temp = new RealSkipBagNode (item, l); + SkipBagNodePtr *temp_forward = temp->forward; + + do + { + SkipBagNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void SkipBag::del( key) +{ + + int l = level; + int curr_level = level; + SkipBagNodePtr *update = new SkipBagNodePtr[max_levels+1]; + SkipBagNodePtr curr = (SkipBagNodePtr)header; + SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipBagNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipBagNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipBagNodePtr SkipBag::rightmost() +{ + SkipBagNodePtr temp; + SkipBagNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipBagNodePtr SkipBag::pred(SkipBagNodePtr t) +{ + SkipBagNodePtr temp, curr = (SkipBagNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipBag::_kill() +{ + SkipBagNode *p = this->header->forward[0]; + + while (p != header) + { + SkipBagNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipBag::clear() +{ + SkipBagNodePtr *buffer_start = header->forward; + SkipBagNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipBagNodePtr)header; +} + +Pix SkipBag::seek( key, Pix i) +{ + SkipBagNodePtr temp; + SkipBagNode *curr = header; + int l = level; + if (i) + curr = (SkipBagNode *)i; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +int SkipBag::nof( item) +{ + int n = 0; + SkipBagNodePtr t = (SkipBagNodePtr)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && EQ(item, t->item)); + } + return n; +} + +void SkipBag::remove( key) +{ + Pix t = seek(key); + while (t != 0) + { + del(key); + t = seek(key); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipBag::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipBag::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipBagNodePtr trail = leftmost(); + SkipBagNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipBaginit::SkipBaginit() +{ + if (!count) + SkipBag::gen = new MLCG(time(0)); + count++; +} + +SkipBaginit::~SkipBaginit() +{ + count--; + if (!count) + delete SkipBag::gen; +} diff --git a/gnu/lib/libg++/g++-include/gen/SkipBag.hP b/gnu/lib/libg++/g++-include/gen/SkipBag.hP new file mode 100644 index 0000000000..1bfe9da446 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipBag.hP @@ -0,0 +1,171 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipBag_h 1 + +#include ".Bag.h" + +#include +#include + +class SkipBag; +class RealSkipBagNode; + +class SkipBagNode +{ +friend class SkipBag; + private: + RealSkipBagNode * * forward; + SkipBagNode(int size); +}; + +class RealSkipBagNode : public SkipBagNode +{ +friend class SkipBag; + private: + item; + RealSkipBagNode( h, int size); +}; + +typedef RealSkipBagNode* SkipBagNodePtr; + +inline SkipBagNode::SkipBagNode(int size) +: forward(new SkipBagNodePtr[size+1]) +{ +} + +inline RealSkipBagNode::RealSkipBagNode( h, int size) +: item(h), + SkipBagNode(size) +{ +} + +class SkipBag : public Bag +{ +friend class SkipBaginit; + protected: + SkipBagNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipBagNodePtr leftmost(void); + SkipBagNodePtr rightmost(void); + SkipBagNodePtr pred(SkipBagNodePtr t); + SkipBagNodePtr succ(SkipBagNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + SkipBag(long size=DEFAULT_INITIAL_CAPACITY); + SkipBag(SkipBag& a); + ~SkipBag(void); + + Pix add( i); + void del( i); + void remove(i); + int nof( i); + int contains( i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + & operator () (Pix i); + Pix seek( i, Pix from = 0); + + Pix last(void); + void prev(Pix& i); + + int OK(void); +}; + +inline SkipBagNodePtr SkipBag::leftmost(void) +{ + return header->forward[0]; +} + +inline SkipBagNodePtr SkipBag::succ(SkipBagNodePtr t) +{ + SkipBagNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix SkipBag::first(void) +{ + return Pix(leftmost()); +} + +inline Pix SkipBag::last(void) +{ + return Pix(rightmost()); +} + +inline void SkipBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipBagNodePtr)i)); +} + +inline & SkipBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipBagNodePtr)i)->item; +} + +inline void SkipBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipBagNodePtr)i)); +} + +inline int SkipBag::contains( key) +{ + return seek(key) != 0; +} + +inline SkipBag::~SkipBag() +{ + _kill(); + delete header; +} + +static class SkipBaginit +{ + public: + SkipBaginit(); + ~SkipBaginit(); + private: + static int count; +} skipBaginit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipMap.ccP b/gnu/lib/libg++/g++-include/gen/SkipMap.ccP new file mode 100644 index 0000000000..8b6afe2edd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipMap.ccP @@ -0,0 +1,307 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include +#include "..SkipMap.h" + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +MLCG* SkipMap::gen = 0; +int SkipMapinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1) n++; + return n; +} + +SkipMap::SkipMap( dflt, long size) +: Map(dflt), + level(0), + header(new SkipMapNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipMapNodePtr) header; +} + +SkipMap::SkipMap(SkipMap& b) +: Map(b.def), + level (0), + header (new SkipMapNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipMapNodePtr)header; + + for (SkipMapNodePtr t = b.leftmost(); t; t = b.succ(t)) + (*this)[t->item] = t->cont; +} + +& SkipMap::operator [] ( item) +{ + SkipMapNodePtr *update = new SkipMapNodePtr[max_levels+1]; + SkipMapNodePtr curr = + (SkipMapNodePtr) this->header; + int l = level; + SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && CMP(temp->item, item) == 0) + { + delete update; + return temp->cont; + } + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipMapNodePtr)header; + }; + + temp = new RealSkipMapNode (item, def, l); + SkipMapNodePtr *temp_forward = temp->forward; + + do + { + SkipMapNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return temp->cont; +} + +void SkipMap::del( key) +{ + + int l = level; + int curr_level = level; + SkipMapNodePtr *update = new SkipMapNodePtr[max_levels+1]; + SkipMapNodePtr curr = (SkipMapNodePtr)header; + SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipMapNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipMapNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipMapNodePtr SkipMap::rightmost() +{ + SkipMapNodePtr temp; + SkipMapNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipMapNodePtr SkipMap::pred(SkipMapNodePtr t) +{ + SkipMapNodePtr temp, curr = (SkipMapNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipMap::_kill() +{ + SkipMapNode *p = this->header->forward[0]; + + while (p != header) + { + SkipMapNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipMap::clear() +{ + SkipMapNodePtr *buffer_start = header->forward; + SkipMapNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipMapNodePtr)header; +} + +Pix SkipMap::seek( key) +{ + SkipMapNodePtr temp; + SkipMapNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipMap::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipMap::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipMapNodePtr trail = leftmost(); + SkipMapNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipMapinit::SkipMapinit() +{ + if (!count) + SkipMap::gen = new MLCG(time(0)); + count++; +} + +SkipMapinit::~SkipMapinit() +{ + count--; + if (!count) + delete SkipMap::gen; +} + + diff --git a/gnu/lib/libg++/g++-include/gen/SkipMap.hP b/gnu/lib/libg++/g++-include/gen/SkipMap.hP new file mode 100644 index 0000000000..65766d64c7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipMap.hP @@ -0,0 +1,176 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipMap_h 1 + +#include "..Map.h" + +#include +#include + +class SkipMap; +class RealSkipMapNode; + +class SkipMapNode +{ +friend class SkipMap; + private: + RealSkipMapNode * * forward; + protected: + SkipMapNode(int size); +}; + +class RealSkipMapNode : public SkipMapNode +{ +friend class SkipMap; + private: + item; + cont; + RealSkipMapNode( h, i, int size); +}; + +typedef RealSkipMapNode* SkipMapNodePtr; + +inline SkipMapNode::SkipMapNode(int size) +: forward(new SkipMapNodePtr[size+1]) +{ +} + +inline RealSkipMapNode::RealSkipMapNode( h, i, int size) +: item(h), cont(i), + SkipMapNode(size) +{ +} + +class SkipMap : public Map +{ +friend class SkipMapinit; + protected: + SkipMapNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipMapNodePtr leftmost(); + SkipMapNodePtr rightmost(); + SkipMapNodePtr pred(SkipMapNodePtr t); + SkipMapNodePtr succ(SkipMapNodePtr t); + void _kill(); + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + SkipMap( dflt, long size=DEFAULT_INITIAL_CAPACITY); + SkipMap(SkipMap& a); + ~SkipMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline SkipMap::~SkipMap() +{ + _kill(); + delete header; +} + +inline SkipMapNodePtr SkipMap::leftmost() +{ + return header->forward[0]==header ? 0 : header->forward[0]; +} + +inline Pix SkipMap::first() +{ + return Pix(leftmost()); +} + +inline Pix SkipMap::last() +{ + return Pix(rightmost()); +} + +inline SkipMapNodePtr SkipMap::succ(SkipMapNodePtr t) +{ + return t->forward[0]==header ? 0 : t->forward[0]; +} + +inline void SkipMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipMapNodePtr)i)); +} + +inline void SkipMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipMapNodePtr)i)); +} + +inline & SkipMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipMapNodePtr)i)->item; +} + +inline & SkipMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipMapNodePtr)i)->cont; +} + +inline int SkipMap::contains( key) +{ + return seek(key) != 0; +} + +static class SkipMapinit +{ + public: + SkipMapinit(); + ~SkipMapinit(); + private: + static int count; +} skipMapinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipSet.ccP b/gnu/lib/libg++/g++-include/gen/SkipSet.ccP new file mode 100644 index 0000000000..a1bf33d0fa --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipSet.ccP @@ -0,0 +1,395 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include +#include + +#include ".SkipSet.h" + +MLCG* SkipSet::gen = 0; +int SkipSetinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +SkipSet::SkipSet(long size) +: level(0), + header(new SkipSetNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (SkipSetNodePtr) header; +} + +SkipSet::SkipSet(SkipSet& b) +: level (0), + header (new SkipSetNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (SkipSetNodePtr)header; + + for (SkipSetNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +/* relationals */ + +int SkipSet::operator == (SkipSet& y) +{ + if (count != y.count) + return 0; + else + { + SkipSetNodePtr t = leftmost(); + SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int SkipSet::operator <= (SkipSet& y) +{ + if (count > y.count) + return 0; + else + { + SkipSetNodePtr t = leftmost(); + SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void SkipSet::operator |=(SkipSet& y) +{ + if (&y == this) return; + SkipSetNodePtr u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void SkipSet::operator &= (SkipSet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + SkipSetNodePtr t = leftmost(); + while (t != 0) + { + SkipSetNodePtr s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void SkipSet::operator -=(SkipSet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + SkipSetNodePtr t = leftmost(); + while (t != 0) + { + SkipSetNodePtr s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +Pix SkipSet::add ( i) +{ + SkipSetNodePtr *update = new SkipSetNodePtr[max_levels+1]; + SkipSetNodePtr curr = (SkipSetNodePtr) this->header; + int l = level; + SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, i) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && CMP(temp->item, i) == 0) + return Pix(temp); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (SkipSetNodePtr)header; + }; + + temp = new RealSkipSetNode (i, l); + SkipSetNodePtr *temp_forward = temp->forward; + + do + { + SkipSetNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void SkipSet::del( key) +{ + + int l = level; + int curr_level = level; + SkipSetNodePtr *update = new SkipSetNodePtr[max_levels+1]; + SkipSetNodePtr curr = (SkipSetNodePtr)header; + SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (CMP(temp->item,key)==0) + { + SkipSetNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + SkipSetNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +SkipSetNodePtr SkipSet::rightmost() +{ + SkipSetNodePtr temp; + SkipSetNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +SkipSetNodePtr SkipSet::pred(SkipSetNodePtr t) +{ + SkipSetNodePtr temp, curr = (SkipSetNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void SkipSet::_kill() +{ + SkipSetNode *p = this->header->forward[0]; + + while (p != header) + { + SkipSetNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void SkipSet::clear() +{ + SkipSetNodePtr *buffer_start = header->forward; + SkipSetNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (SkipSetNodePtr)header; +} + +Pix SkipSet::seek( key) +{ + SkipSetNodePtr temp; + SkipSetNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int SkipSet::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int SkipSet::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + SkipSetNodePtr trail = leftmost(); + SkipSetNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +SkipSetinit::SkipSetinit() +{ + if (!count) + SkipSet::gen = new MLCG(time(0)); + count++; +} + +SkipSetinit::~SkipSetinit() +{ + count--; + if (!count) + delete SkipSet::gen; +} diff --git a/gnu/lib/libg++/g++-include/gen/SkipSet.hP b/gnu/lib/libg++/g++-include/gen/SkipSet.hP new file mode 100644 index 0000000000..cd95305239 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipSet.hP @@ -0,0 +1,187 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _SkipSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SkipSet_h 1 + +#include ".Set.h" + +#include +#include + +class SkipSet; +class RealSkipSetNode; + +class SkipSetNode +{ +friend class SkipSet; + private: + RealSkipSetNode * * forward; + SkipSetNode(int size); +}; + +class RealSkipSetNode : public SkipSetNode +{ +friend class SkipSet; + private: + item; + RealSkipSetNode( h, int size); +}; + +typedef RealSkipSetNode* SkipSetNodePtr; + +inline SkipSetNode::SkipSetNode(int size) +: forward(new SkipSetNodePtr[size+1]) +{ +} + +inline RealSkipSetNode::RealSkipSetNode( h, int size) +: item(h), + SkipSetNode(size) +{ +} + +class SkipSet : public Set +{ +friend class SkipSetinit; + protected: + SkipSetNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + SkipSetNodePtr leftmost(void); + SkipSetNodePtr rightmost(void); + SkipSetNodePtr pred(SkipSetNodePtr t); + SkipSetNodePtr succ(SkipSetNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + public: + SkipSet(long size=DEFAULT_INITIAL_CAPACITY); + SkipSet(SkipSet& a); + ~SkipSet(); + + Pix add( i); + void del( i); + int contains( i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + & operator () (Pix i); + Pix seek( i); + + Pix last(void); + void prev(Pix& i); + + void operator |= (SkipSet& b); + void operator -= (SkipSet& b); + void operator &= (SkipSet& b); + + int operator == (SkipSet& b); + int operator != (SkipSet& b); + int operator <= (SkipSet& b); + + int OK(void); +}; + +/* + * A little overkill on the inlines. + * + */ + +inline SkipSet::~SkipSet(void) +{ + _kill(); + delete header; +} + +inline int SkipSet::operator != (SkipSet& b) +{ + return ! (*this == b); +} + +inline SkipSetNodePtr SkipSet::leftmost(void) +{ + return header->forward[0]; +} + +inline SkipSetNodePtr SkipSet::succ(SkipSetNodePtr t) +{ + SkipSetNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix SkipSet::first(void) +{ + return Pix(leftmost()); +} + +inline Pix SkipSet::last(void) +{ + return Pix(rightmost()); +} + +inline void SkipSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SkipSetNodePtr)i)); +} + +inline void SkipSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SkipSetNodePtr)i)); +} + +inline & SkipSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SkipSetNodePtr)i)->item; +} + + +inline int SkipSet::contains( key) +{ + return seek(key) != 0; +} + +static class SkipSetinit +{ + public: + SkipSetinit(); + ~SkipSetinit(); + private: + static int count; +} skipSetinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayBag.ccP b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP new file mode 100644 index 0000000000..ff02a992a6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP @@ -0,0 +1,445 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplayBag.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayBag::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayBag::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayBag::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayBag::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + + +Pix SplayBag::seek( key, Pix i) +{ + if (root == 0) return 0; + + SplayNode* t = (SplayNode*) i; + if (t != 0) + { + int cmp = CMP(key, t->item); + if (cmp == 0) + { + t = succ(t); + if (t != 0 && EQ(key, t->item)) + return Pix(t); + else + return 0; + } + else if (cmp < 0) + return 0; + } + + t = root; + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + if (comp != 0) + return 0; + else + { + l = pred(t); + while (l != 0 && EQ(l->item, key)) { t = l; l = pred(l); } + return Pix(t); + } +} + +int SplayBag::nof( item) +{ + int n = 0; + SplayNode* t = (SplayNode*)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && EQ(item, t->item)); + } + return n; +} + +Pix SplayBag::add( item) +{ + ++count; + SplayNode* newnode = new SplayNode(item); + SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = CMP(item, t->item); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void SplayBag::_del(SplayNode* t) +{ + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplayBag::remove( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + while (t != 0) + { + _del(t); + t = (SplayNode*)(seek(key)); + } +} + + +void SplayBag::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayBag::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int SplayBag::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) <= 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/SplayBag.hP b/gnu/lib/libg++/g++-include/gen/SplayBag.hP new file mode 100644 index 0000000000..9d7fcad1dd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayBag.hP @@ -0,0 +1,144 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayBag_h 1 + +#include ".Bag.h" +#include ".SplayNode.h" + +class SplayBag : public Bag +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + void _del(SplayNode* t); + +public: + SplayBag(); + SplayBag(SplayBag& a); + ~SplayBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline SplayBag::~SplayBag() +{ + _kill(root); +} + +inline SplayBag::SplayBag() +{ + root = 0; + count = 0; +} + +inline SplayBag::SplayBag(SplayBag& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayBag::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayBag::last() +{ + return Pix(rightmost()); +} + +inline void SplayBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplayBag::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayBag::contains( key) +{ + return seek(key) != 0; +} + +inline void SplayBag::del( key) +{ + _del((SplayNode*)(seek(key))); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayMap.ccP b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP new file mode 100644 index 0000000000..4be340db0f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP @@ -0,0 +1,401 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include "..SplayMap.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayMap::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayMap::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayMap::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayMap::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplayMap::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +& SplayMap::operator [] ( item) +{ + SplayNode* t = root; + if (t == 0) + { + ++count; + root = new SplayNode(item, def); + return root->cont; + } + int comp = CMP(item, t->item); + if (comp == 0) + return t->cont; + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new SplayNode(item, def); + comp = 0; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return root->cont; +} + +void SplayMap::del( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplayMap::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayMap::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, t->cont, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + + +int SplayMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplayMap.hP b/gnu/lib/libg++/g++-include/gen/SplayMap.hP new file mode 100644 index 0000000000..ced95378ab --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayMap.hP @@ -0,0 +1,154 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayMap_h 1 + +#include "..Map.h" + +#ifndef _SplayNode +#define _SplayNode 1 + +struct SplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; + item; + cont; + SplayNode( h, c, + SplayNode* l=0, + SplayNode* r=0); + ~SplayNode(); +}; + + +inline SplayNode::SplayNode( h, c, + SplayNode* l, + SplayNode* r) + :item(h), cont(c), lt(l), rt(r), par(0) {} + +inline SplayNode::~SplayNode() {} + +typedef SplayNode* SplayNodePtr; + +#endif + +class SplayMap : public Map +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplayMap( dflt); + SplayMap(SplayMap& a); + ~SplayMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline SplayMap::~SplayMap() +{ + _kill(root); +} + +inline SplayMap::SplayMap( dflt) :Map(dflt) +{ + root = 0; +} + +inline SplayMap::SplayMap(SplayMap& b) :Map(b.def) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayMap::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayMap::last() +{ + return Pix(rightmost()); +} + +inline void SplayMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline & SplayMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->cont; +} + +inline void SplayMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayMap::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayNode.ccP b/gnu/lib/libg++/g++-include/gen/SplayNode.ccP new file mode 100644 index 0000000000..9dfb1d8c06 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".SplayNode.h" diff --git a/gnu/lib/libg++/g++-include/gen/SplayNode.hP b/gnu/lib/libg++/g++-include/gen/SplayNode.hP new file mode 100644 index 0000000000..a196861fc9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayNode.hP @@ -0,0 +1,44 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _SplayNode +#define _SplayNode 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include ".defs.h" + +struct SplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; + item; + SplayNode( h, SplayNode* l=0, SplayNode* r=0); + ~SplayNode(); +}; + + +inline SplayNode::SplayNode( h, SplayNode* l, SplayNode* r) +:item(h), lt(l), rt(r), par(0) {} + +inline SplayNode::~SplayNode() {} + +typedef SplayNode* SplayNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP new file mode 100644 index 0000000000..0740cd9a93 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP @@ -0,0 +1,523 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplayPQ.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplayPQ::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplayPQ::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplayPQ::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplayPQ::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplayPQ::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +Pix SplayPQ::enq( item) +{ + ++count; + SplayNode* newnode = new SplayNode(item); + SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = CMP(item, t->item); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + + +void SplayPQ::del(Pix pix) +{ + SplayNode* t = (SplayNode*)pix; + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + +& SplayPQ::front() +{ + if (root == 0) + error ("min: empty tree\n"); +// else + { + SplayNode* t = root; + SplayNode* l = root->lt; + for(;;) + { + if (l == 0) + { + root = t; + root->par = 0; + return root->item; + } + else + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + l->rt = t; t->par = l; + t = l; + l = l->lt; + } + } + } +} + +void SplayPQ::del_front() +{ + if (root != 0) + { + --count; + SplayNode* t = root; + SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + delete t; + } + else + { + for(;;) + { + SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + delete l; + break; + } + else + { + SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + delete ll; + break; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + + SplayPQ::deq() +{ + if (root == 0) + error("deq: empty tree"); +// else + { + --count; + SplayNode* t = root; + SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + res = t->item; + delete t; + return res; + } + else + { + for(;;) + { + SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + res = l->item; + delete l; + return res; + } + else + { + SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + res = ll->item; + delete ll; + return res; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + + +void SplayPQ::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplayPQ::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int SplayPQ::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplayPQ.hP b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP new file mode 100644 index 0000000000..c75c4a0529 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP @@ -0,0 +1,123 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplayPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplayPQ_h 1 + +#include ".PQ.h" +#include ".SplayNode.h" + +class SplayPQ : public PQ +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplayPQ(); + SplayPQ(SplayPQ& a); + virtual ~SplayPQ(); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + Pix last(); + void next(Pix& i); + void prev(Pix& i); + & operator () (Pix i); + void del(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + + +inline SplayPQ::~SplayPQ() +{ + _kill(root); +} + +inline SplayPQ::SplayPQ() +{ + root = 0; + count = 0; +} + +inline SplayPQ::SplayPQ(SplayPQ& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix SplayPQ::first() +{ + return Pix(leftmost()); +} + +inline Pix SplayPQ::last() +{ + return Pix(rightmost()); +} + +inline void SplayPQ::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplayPQ::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplayPQ::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplayPQ::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplayPQ::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplaySet.ccP b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP new file mode 100644 index 0000000000..bba5601c7e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP @@ -0,0 +1,499 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".SplaySet.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + SplayNode* lt; + SplayNode* rt; + SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +SplayNode* SplaySet::leftmost() +{ + SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +SplayNode* SplaySet::rightmost() +{ + SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +SplayNode* SplaySet::succ(SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +SplayNode* SplaySet::pred(SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix SplaySet::seek( key) +{ + SplayNode* t = root; + if (t == 0) + return 0; + + int comp = CMP(key, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = CMP(key, t->item); + } + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + + +Pix SplaySet::add( item) +{ + SplayNode* t = root; + if (t == 0) + { + ++count; + root = new SplayNode(item); + return Pix(root); + } + int comp = CMP(item, t->item); + if (comp == 0) + return Pix(t); + + SplayNode* dummy = (SplayNode*)(&_dummy_null); + SplayNode* l = dummy; + SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new SplayNode(item); + comp = 0; + } + else + comp = CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void SplaySet::del( key) +{ + SplayNode* t = (SplayNode*)(seek(key)); + if (t == 0) return; + + SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + SplayNode* r = t->rt; + SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void SplaySet::_kill(SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +SplayNode* SplaySet::_copy(SplayNode* t) +{ + if (t != 0) + { + SplayNode* l = _copy(t->lt); + SplayNode* r = _copy(t->rt); + SplayNode* x = new SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +/* relationals */ + +int SplaySet::operator == (SplaySet& y) +{ + if (count != y.count) + return 0; + else + { + SplayNode* t = leftmost(); + SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int SplaySet::operator <= (SplaySet& y) +{ + if (count > y.count) + return 0; + else + { + SplayNode* t = leftmost(); + SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void SplaySet::operator |=(SplaySet& y) +{ + if (&y == this) return; + SplayNode* u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void SplaySet::operator &= (SplaySet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + SplayNode* t = leftmost(); + while (t != 0) + { + SplayNode* s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void SplaySet::operator -=(SplaySet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + SplayNode* t = leftmost(); + while (t != 0) + { + SplayNode* s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +int SplaySet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + SplayNode* trail = leftmost(); + SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplaySet.hP b/gnu/lib/libg++/g++-include/gen/SplaySet.hP new file mode 100644 index 0000000000..cf50b97554 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplaySet.hP @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _SplaySet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SplaySet_h 1 + +#include ".Set.h" +#include ".SplayNode.h" + +class SplaySet : public Set +{ +protected: + SplayNode* root; + + SplayNode* leftmost(); + SplayNode* rightmost(); + SplayNode* pred(SplayNode* t); + SplayNode* succ(SplayNode* t); + void _kill(SplayNode* t); + SplayNode* _copy(SplayNode* t); + +public: + SplaySet(); + SplaySet(SplaySet& a); + ~SplaySet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + Pix last(); + void prev(Pix& i); + + void operator |= (SplaySet& b); + void operator -= (SplaySet& b); + void operator &= (SplaySet& b); + + int operator == (SplaySet& b); + int operator != (SplaySet& b); + int operator <= (SplaySet& b); + + int OK(); +}; + + +inline SplaySet::~SplaySet() +{ + _kill(root); +} + +inline SplaySet::SplaySet() +{ + root = 0; + count = 0; +} + +inline SplaySet::SplaySet(SplaySet& b) +{ + count = b.count; + root = _copy(b.root); +} + + +inline int SplaySet::operator != (SplaySet& b) +{ + return ! (*this == b); +} + +inline Pix SplaySet::first() +{ + return Pix(leftmost()); +} + +inline Pix SplaySet::last() +{ + return Pix(rightmost()); +} + +inline void SplaySet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((SplayNode*)i)); +} + +inline void SplaySet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((SplayNode*)i)); +} + +inline & SplaySet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((SplayNode*)i)->item; +} + +inline void SplaySet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int SplaySet::contains( key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Stack.ccP b/gnu/lib/libg++/g++-include/gen/Stack.ccP new file mode 100644 index 0000000000..efb6b8edbd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Stack.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".Stack.h" + +Stack::~Stack() {} + +void Stack::error(const char* msg) +{ + (*lib_error_handler)("Stack", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Stack.hP b/gnu/lib/libg++/g++-include/gen/Stack.hP new file mode 100644 index 0000000000..37acb2fac5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Stack.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Stack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Stack_h + +#include + +#include ".defs.h" + +class Stack +{ +public: + Stack() { } + virtual ~Stack(); + + virtual void push( item) = 0; + virtual pop() = 0; + virtual & top() = 0; + virtual void del_top() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + virtual void clear() = 0; + + void error(const char*); + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHBag.ccP b/gnu/lib/libg++/g++-include/gen/VHBag.ccP new file mode 100644 index 0000000000..81a20eb140 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHBag.ccP @@ -0,0 +1,264 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".VHBag.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHBag::VHBag(unsigned int sz) +{ + tab = new [size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +VHBag::VHBag(VHBag& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHBag::seek( key, Pix p) +{ + * t = (*) p; + if (t == 0 || !EQ(*t, key)) + { + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } + else + { + int seent = 0; + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (&tab[h] == t) + seent = 1; + else if (seent && status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } +} + +int VHBag::nof( item) +{ + int n = 0; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + unsigned int firsth = size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return n; + else if (h != firsth && status[h] == VALIDCELL && EQ(item, tab[h])) + { + ++n; + if (firsth >= size) + firsth = h; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return n; +} + + +Pix VHBag::add( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); +} + + +void VHBag::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void VHBag::remove( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void VHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHBag::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VHBag::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHBag::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VHBag::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHBag.hP b/gnu/lib/libg++/g++-include/gen/VHBag.hP new file mode 100644 index 0000000000..72c774a559 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHBag.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHBag_h 1 + +#include ".Bag.h" + + +class VHBag : public Bag +{ +protected: + * tab; + char* status; + unsigned int size; + +public: + VHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + VHBag(VHBag& a); + ~VHBag(); + + Pix add( item); + void del( item); + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item, Pix from = 0); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline VHBag::~VHBag() +{ + delete [] tab; + delete status; +} + + +inline int VHBag::capacity() +{ + return size; +} + +inline int VHBag::contains( key) +{ + return seek(key) != 0; +} + +inline & VHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHMap.ccP b/gnu/lib/libg++/g++-include/gen/VHMap.ccP new file mode 100644 index 0000000000..d6b60e997a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHMap.ccP @@ -0,0 +1,210 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "..VHMap.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHMap::VHMap( dflt, unsigned int sz) + :Map(dflt) +{ + tab = new [size = sz]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; +} + +VHMap::VHMap(VHMap& a) : Map(a.def) +{ + tab = new [size = a.size]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHMap::seek( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +& VHMap::operator []( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + ++count; + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + cont[bestspot] = def; + return cont[bestspot]; + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (EQ(tab[h],item)) + return cont[h]; + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + + ++count; + status[bestspot] = VALIDCELL; + tab[bestspot] = item; + cont[bestspot] = def; + return cont[bestspot]; +} + + +void VHMap::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void VHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHMap::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + * oldcont = cont; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + cont = new [size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) + if (oldstatus[i] == VALIDCELL) + (*this)[oldtab[i]] = oldcont[i]; + delete [] oldtab; + delete [] oldcont; + delete oldstatus; +} + +Pix VHMap::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHMap::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VHMap::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHMap.hP b/gnu/lib/libg++/g++-include/gen/VHMap.hP new file mode 100644 index 0000000000..ac8fe4d219 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHMap.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHMap_h 1 + +#include "..Map.h" + + +class VHMap : public Map +{ +protected: + * tab; + * cont; + char* status; + unsigned int size; + +public: + VHMap( dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + VHMap(VHMap& a); + ~VHMap(); + + & operator [] ( key); + + void del( key); + + Pix first(); + void next(Pix& i); + & key(Pix i); + & contents(Pix i); + + Pix seek( key); + int contains( key); + + void clear(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + +inline VHMap::~VHMap() +{ + delete [] tab; + delete [] cont; + delete [] status; +} + +inline int VHMap::contains( key) +{ + return seek(key) != 0; +} + +inline & VHMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +inline & VHMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return cont[((unsigned)(i) - (unsigned)(tab)) / sizeof()]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHSet.ccP b/gnu/lib/libg++/g++-include/gen/VHSet.ccP new file mode 100644 index 0000000000..a78b319834 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHSet.ccP @@ -0,0 +1,263 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".VHSet.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VHSet::VHSet(unsigned int sz) +{ + tab = new [size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +VHSet::VHSet(VHSet& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix VHSet::seek( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +Pix VHSet::add( item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (EQ(tab[h],item)) + return Pix(&tab[h]); + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + +} + + +void VHSet::del( key) +{ + unsigned int hashval = HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void VHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void VHSet::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + * oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VHSet::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VHSet::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + +int VHSet:: operator == (VHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int VHSet::operator <= (VHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void VHSet::operator |= (VHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void VHSet::operator &= (VHSet& b) +{ + if (&b == this || count == 0) + return; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void VHSet::operator -= (VHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int VHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHSet.hP b/gnu/lib/libg++/g++-include/gen/VHSet.hP new file mode 100644 index 0000000000..b7b3a3578c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHSet.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VHSet_h 1 + +#include ".Set.h" + + + +class VHSet : public Set +{ +protected: + * tab; + char* status; + unsigned int size; + +public: + VHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + VHSet(VHSet& a); + ~VHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (VHSet& b); + void operator -= (VHSet& b); + void operator &= (VHSet& b); + + int operator == (VHSet& b); + int operator != (VHSet& b); + int operator <= (VHSet& b); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline VHSet::~VHSet() +{ + delete [] tab; + delete status; +} + + +inline int VHSet::capacity() +{ + return size; +} + +inline int VHSet::contains( key) +{ + return seek(key) != 0; +} + +inline & VHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((*)i); +} + +inline int VHSet::operator != (VHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VOHSet.ccP b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP new file mode 100644 index 0000000000..c5d4557a4c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP @@ -0,0 +1,308 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VOHSet.h" + + +/* codes for status fields */ +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +VOHSet::VOHSet(int sz) +{ +// The size of the hash table is always the smallest power of 2 >= the size +// indicated by the user. This allows several optimizations, including +// the use of actual double hashing and elimination of the mod instruction. + + size = 1; + while (size < sz) size <<= 1; + tab = new [size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +VOHSet::VOHSet(VOHSet& a) +{ + tab = new [size = a.size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + +Pix VOHSet::seek( key) +{ +// Uses ordered double hashing to perform a search of the table. +// This greatly speeds up the average-case time for an unsuccessful search. + + unsigned hashval = HASH(key); + + // We can avoid the mod operation since size is a power of 2. + unsigned h = hashval & (size - 1); + + // The increment must be odd, since all odd numbers are relatively + // prime to a power of 2!! + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + // There is always at least 1 empty cell, so this loop is guaranteed to halt! + while (status[h] != EMPTYCELL) + { + int cmp = CMP (key, tab[h]); + if (cmp == 0) + { + if (status[h] == VALIDCELL) + return Pix(&tab[h]); + else + return 0; + } + else if (cmp > 0) + return 0; + else + h = ((h + inc) & (size - 1)); + } + return 0; +} + +// This adds an item if it doesn't already exist. By performing the initial +// comparison we assure that the table always contains at least 1 empty +// spot. This speeds up later searching by a constant factor. +// The insertion algorithm uses ordered double hashing. See Standish's +// 1980 ``Data Structure's Techniques'' book for details. + +Pix VOHSet::add( x) +{ + if (size <= cnt+1) + resize(); + + unsigned hashval = HASH(x); + unsigned h = hashval & (size - 1); + + if (status[h] != VALIDCELL) // save some work if possible + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = x; + status[h] = VALIDCELL; + return Pix(&tab[h]); + } + int cmp = CMP(x, tab[h]); + if (cmp == 0) + return Pix(&tab[h]); + + item = x; + Pix mypix = 0; + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + for (;;) + { + if (cmp < 0) + { + temp = tab[h]; + tab[h] = item; + item = temp; + if (mypix == 0) mypix = Pix(&tab[h]); + inc = ((((HASH(item) / size) << 1) + 1) & (size - 1)); + h = ((h + inc) & (size - 1)); + if (status[h] != EMPTYCELL) cmp = CMP(item, tab[h]); + } + else + h = ((h + inc) & (size - 1)); + if (status[h] != VALIDCELL) + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = item; + status[h] = VALIDCELL; + return (mypix == 0)? Pix(&tab[h]) : mypix; + } + } +} + + +void VOHSet::del( key) +{ +// This performs a deletion by marking the item's status field. +// Note that we only decrease the count, *not* the cnt, since this +// would cause trouble for subsequent steps in the algorithm. See +// Reingold and Hanson's ``Data Structure's'' book for a justification +// of this approach. + + unsigned hashval = HASH(key); + unsigned h = hashval & (size - 1); + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + while (status[h] != EMPTYCELL) + { + int cmp = CMP(key, tab[h]); + if (cmp > 0) + h = ((h + inc) & (size - 1)); + else if (status[h] == VALIDCELL && cmp == 0) + { + status[h] = DELETEDCELL; + count--; + return; + } + else + return; + } +} + +void VOHSet::clear() +{ + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +void VOHSet::resize(int newsize) +{ + if (newsize <= count) + newsize = count; + int s = 1; + while (s <= newsize) s <<= 1; + newsize = s; + + * oldtab = tab; + char* oldstatus = status; + int oldsize = size; + tab = new [size = newsize]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix VOHSet::first() +{ + for (int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void VOHSet::next(Pix& i) +{ + if (i == 0) return; + int pos = ((unsigned)i - (unsigned)tab) / sizeof() + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int VOHSet:: operator == (VOHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int VOHSet:: operator != (VOHSet& b) +{ + return !(*this == b); +} + +int VOHSet::operator <= (VOHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void VOHSet::operator |= (VOHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void VOHSet::operator &= (VOHSet& b) +{ + if (&b == this || count == 0) + return; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void VOHSet::operator -= (VOHSet& b) +{ + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int VOHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} + + + diff --git a/gnu/lib/libg++/g++-include/gen/VOHSet.hP b/gnu/lib/libg++/g++-include/gen/VOHSet.hP new file mode 100644 index 0000000000..94decaad12 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VOHSet.hP @@ -0,0 +1,88 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VOHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VOHSet_h 1 + +#include ".Set.h" + + + +class VOHSet : public Set +{ + * tab; + char* status; + int size; + int cnt; // keeps track of VALIDCELLs and DELETEDCELLs + +public: + VOHSet(int sz = DEFAULT_INITIAL_CAPACITY); + VOHSet(VOHSet&); + ~VOHSet(); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + Pix seek( item); + + void operator |= (VOHSet& b); + void operator -= (VOHSet& b); + void operator &= (VOHSet& b); + + int operator == (VOHSet& b); + int operator != (VOHSet& b); + int operator <= (VOHSet& b); + + int capacity(); + void resize(int newsize = 0); + + int OK(); +}; + + +inline VOHSet::~VOHSet() +{ + delete [] tab; + delete status; +} + + +inline int VOHSet::contains( key) +{ + return seek(key) != 0; +} + + +inline & VOHSet::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return *((*)p); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VQueue.ccP b/gnu/lib/libg++/g++-include/gen/VQueue.ccP new file mode 100644 index 0000000000..1181b3f50d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VQueue.ccP @@ -0,0 +1,83 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VQueue.h" + +VQueue::VQueue(VQueue& b) +:size(b.size), cnt(b.cnt), inp(b.inp), outp(b.outp), s(new [b.size]) +{ + int j = outp; + for (int i = 0; i < cnt; ++i) + { + s[j] = b.s[j]; + if (++j == size) j = 0; + } +} + +void VQueue::operator = (VQueue& b) +{ + if (&b == this) return; + if (size != b.size) + { + delete [] s; + s = new [b.size]; + size = b.size; + } + inp = b.inp; outp = b.outp; cnt = b.cnt; + int j = outp; + for (int i = 0; i < cnt; ++i) + { + s[j] = b.s[j]; + if (++j == size) j = 0; + } +} + + +void VQueue::resize(int newsz) +{ + if (newsz < cnt) + error("resize: new size too small"); + * news = new [newsz]; + int j = outp; + for (int i = 0; i < cnt; ++i) + { + news[i] = s[j]; + if (++j == size) j = 0; + } + inp = j; + outp = 0; + delete [] s; + s = news; + size = newsz; +} + +int VQueue::OK() +{ + int v = s != 0; // have space + v &= size >= 0; // a legal size + v &= inp >= 0 && inp <= size; // pointers with bounds + v &= outp >= 0 && outp <= size; + int c = (size + inp - outp) % size; + v &= cnt == size || cnt == c; // correct count + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VQueue.hP b/gnu/lib/libg++/g++-include/gen/VQueue.hP new file mode 100644 index 0000000000..cce2c85d24 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VQueue.hP @@ -0,0 +1,130 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VQueue_h 1 + +#include ".Queue.h" + +class VQueue : public Queue +{ +protected: + int size; + int cnt; + int inp; + int outp; + * s; + +public: + + VQueue(int sz = DEFAULT_INITIAL_CAPACITY); + VQueue(VQueue&); + ~VQueue(); + + void operator = (VQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + int length(); + int empty(); + int full(); + + int capacity(); + void resize(int sz); + void clear(); + + int OK(); +}; + + +inline VQueue::VQueue(int sz) +{ + s = new [size = sz]; + cnt = inp = outp = 0; +} + +inline VQueue::~VQueue() +{ + delete [] s; +} + +inline void VQueue::clear() +{ + inp = outp = 0; + cnt = 0; +} + +inline int VQueue::empty() +{ + return cnt <= 0; +} + +inline int VQueue::capacity() +{ + return size; +} + +inline int VQueue::full() +{ + return cnt >= size; +} + +inline int VQueue::length() +{ + return cnt; +} + +inline void VQueue::enq( item) +{ + if (cnt >= size) error("enq to full Queue."); + ++cnt; + s[inp] = item; + if (++inp == size) inp = 0; +} + +inline VQueue::deq() +{ + if (cnt <= 0) error("deq from empty Queue."); + --cnt; + int i = outp; + if (++outp == size) outp = 0; + return s[i]; +} + + +inline void VQueue::del_front() +{ + if (cnt <= 0) error("delete from empty Queue."); + --cnt; + if (++outp == size) outp = 0; +} + +inline & VQueue::front() +{ + if (empty()) error("top from empty Queue."); + return s[outp]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VStack.ccP b/gnu/lib/libg++/g++-include/gen/VStack.ccP new file mode 100644 index 0000000000..5203d51341 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VStack.ccP @@ -0,0 +1,66 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include ".VStack.h" + +// error handling + + +VStack::VStack(VStack& b) +:size(b.size), ptr(b.ptr), s(new [b.size]) +{ + for (int i = 0; i < ptr; ++i) s[i] = b.s[i]; +} + +void VStack::operator = (VStack& b) +{ + if (&b == this) return; + if (size < b.ptr) + { + delete [] s; + s = new [b.size]; + size = b.size; + } + ptr = b.ptr; + for (int i = 0; i < ptr; ++i) s[i] = b.s[i]; +} + + +void VStack::resize(int newsz) +{ + if (newsz < ptr) error("resize: new size too small"); + * news = new [newsz]; + for (int i = 0; i < ptr; ++i) news[i] = s[i]; + delete [] s; + s = news; + size = newsz; +} + +int VStack::OK() +{ + int v = s != 0; // have space + v &= size >= 0; // a legal size + v &= ptr <= size; // ptr within bounds + v &= ptr >= 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VStack.hP b/gnu/lib/libg++/g++-include/gen/VStack.hP new file mode 100644 index 0000000000..c8190bf064 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VStack.hP @@ -0,0 +1,120 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _VStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _VStack_h 1 + +#include ".Stack.h" + +class VStack : public Stack +{ +protected: + int size; + int ptr; + * s; + +public: + + VStack(int sz = DEFAULT_INITIAL_CAPACITY); + VStack(VStack&); + ~VStack(); + + void operator = (VStack&); + void push( item); + pop(); + & top(); + void del_top(); + + int length(); + int empty(); + int full(); + void clear(); + + void resize(int sz); + int capacity(); + + int OK(); +}; + + +inline VStack::VStack(int sz) +{ + s = new [size = sz]; + ptr = 0; +} + +inline VStack::~VStack() +{ + delete [] s; +} + +inline void VStack::clear() +{ + ptr = 0; +} + +inline int VStack::capacity() +{ + return size; +} + +inline int VStack::empty() +{ + return ptr == 0; +} + +inline int VStack::full() +{ + return ptr == size; +} + +inline int VStack::length() +{ + return ptr; +} + +inline void VStack::push( item) +{ + if (full()) error("push to full stack."); + s[ptr++] = item; +} + +inline VStack::pop() +{ + if (empty()) error("pop from empty stack."); + return s[--ptr]; +} + + +inline void VStack::del_top() +{ + if (empty()) error("del_top from empty stack."); + --ptr; +} + +inline & VStack::top() +{ + if (empty()) error("top from empty stack."); + return s[ptr-1]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Vec.ccP b/gnu/lib/libg++/g++-include/gen/Vec.ccP new file mode 100644 index 0000000000..c9cbfb2109 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Vec.ccP @@ -0,0 +1,470 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include +#include +#include ".Vec.h" + +// error handling + + +void default_Vec_error_handler(const char* msg) +{ + cerr << "Fatal Vec error. " << msg << "\n"; + exit(1); +} + +one_arg_error_handler_t Vec_error_handler = default_Vec_error_handler; + +one_arg_error_handler_t set_Vec_error_handler(one_arg_error_handler_t f) +{ + one_arg_error_handler_t old = Vec_error_handler; + Vec_error_handler = f; + return old; +} + +void Vec::error(const char* msg) +{ + (*Vec_error_handler)(msg); +} + +void Vec::range_error() +{ + (*Vec_error_handler)("Index out of range."); +} + +Vec::Vec(Vec& v) +{ + s = new [len = v.len]; + * top = &(s[len]); + * t = s; + * u = v.s; + while (t < top) *t++ = *u++; +} + +Vec::Vec(int l, fill_value) +{ + s = new [len = l]; + * top = &(s[len]); + * t = s; + while (t < top) *t++ = fill_value; +} + + +Vec& Vec::operator = (Vec& v) +{ + if (this != &v) + { + delete [] s; + s = new [len = v.len]; + * top = &(s[len]); + * t = s; + * u = v.s; + while (t < top) *t++ = *u++; + } + return *this; +} + +void Vec::apply(Procedure f) +{ + * top = &(s[len]); + * t = s; + while (t < top) (*f)(*t++); +} + +// can't just realloc since there may be need for constructors/destructors +void Vec::resize(int newl) +{ + * news = new [newl]; + * p = news; + int minl = (len < newl)? len : newl; + * top = &(s[minl]); + * t = s; + while (t < top) *p++ = *t++; + delete [] s; + s = news; + len = newl; +} + +Vec concat(Vec & a, Vec & b) +{ + int newl = a.len + b.len; + * news = new [newl]; + * p = news; + * top = &(a.s[a.len]); + * t = a.s; + while (t < top) *p++ = *t++; + top = &(b.s[b.len]); + t = b.s; + while (t < top) *p++ = *t++; + return Vec(newl, news); +} + + +Vec combine(Combiner f, Vec& a, Vec& b) +{ + int newl = (a.len < b.len)? a.len : b.len; + * news = new [newl]; + * p = news; + * top = &(a.s[newl]); + * t = a.s; + * u = b.s; + while (t < top) *p++ = (*f)(*t++, *u++); + return Vec(newl, news); +} + + Vec::reduce(Combiner f, base) +{ + r = base; + * top = &(s[len]); + * t = s; + while (t < top) r = (*f)(r, *t++); + return r; +} + +Vec reverse(Vec& a) +{ + * news = new [a.len]; + if (a.len != 0) + { + * lo = news; + * hi = &(news[a.len - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } + return Vec(a.len, news); +} + +void Vec::reverse() +{ + if (len != 0) + { + * lo = s; + * hi = &(s[len - 1]); + while (lo < hi) + { + tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } +} + +int Vec::index( targ) +{ + for (int i = 0; i < len; ++i) if (EQ(targ, s[i])) return i; + return -1; +} + +Vec map(Mapper f, Vec& a) +{ + * news = new [a.len]; + * p = news; + * top = &(a.s[a.len]); + * t = a.s; + while(t < top) *p++ = (*f)(*t++); + return Vec(a.len, news); +} + +int operator == (Vec& a, Vec& b) +{ + if (a.len != b.len) + return 0; + * top = &(a.s[a.len]); + * t = a.s; + * u = b.s; + while (t < top) if (!(EQ(*t++, *u++))) return 0; + return 1; +} + +void Vec::fill( val, int from, int n) +{ + int to; + if (n < 0) + to = len - 1; + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *t++ = val; +} + +Vec Vec::at(int from, int n) +{ + int to; + if (n < 0) + { + n = len - from; + to = len - 1; + } + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + * news = new [n]; + * p = news; + * t = &(s[from]); + * top = &(s[to]); + while (t <= top) *p++ = *t++; + return Vec(n, news); +} + +Vec merge(Vec & a, Vec & b, Comparator f) +{ + int newl = a.len + b.len; + * news = new [newl]; + * p = news; + * topa = &(a.s[a.len]); + * as = a.s; + * topb = &(b.s[b.len]); + * bs = b.s; + + for (;;) + { + if (as >= topa) + { + while (bs < topb) *p++ = *bs++; + break; + } + else if (bs >= topb) + { + while (as < topa) *p++ = *as++; + break; + } + else if ((*f)(*as, *bs) <= 0) + *p++ = *as++; + else + *p++ = *bs++; + } + return Vec(newl, news); +} + +static int gsort(*, int, Comparator); + +void Vec::sort (Comparator compar) +{ + gsort(s, len, compar); +} + + +// An adaptation of Schmidt's new quicksort + +static inline void SWAP(* A, * B) +{ + tmp = *A; *A = *B; *B = tmp; +} + +/* This should be replaced by a standard ANSI macro. */ +#define BYTES_PER_WORD 8 +#define BYTES_PER_LONG 4 + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ + +#define STACK_SIZE (BYTES_PER_WORD * BYTES_PER_LONG) +#define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0) +#define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0) +#define STACK_NOT_EMPTY (stack < top) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that + store the next array partition to sort. To save time, this + maximum amount of space required to store an array of + MAX_INT is allocated on the stack. Assuming a 32-bit integer, + this needs only 32 * sizeof (stack_node) == 136 bits. Pretty + cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segements. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (n) + stack size is needed! */ + +static int gsort ( *base_ptr, int total_elems, Comparator cmp) +{ +/* Stack node declarations used to store unfulfilled partition obligations. */ + struct stack_node { *lo; *hi; }; + pivot_buffer; + int max_thresh = MAX_THRESH; + + if (total_elems > MAX_THRESH) + { + *lo = base_ptr; + *hi = lo + (total_elems - 1); + *left_ptr; + *right_ptr; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) + { + { + *pivot = &pivot_buffer; + { + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ + + *mid = lo + ((hi - lo) >> 1); + + if ((*cmp) (*mid, *lo) < 0) + SWAP (mid, lo); + if ((*cmp) (*hi, *mid) < 0) + { + SWAP (mid, hi); + if ((*cmp) (*mid, *lo) < 0) + SWAP (mid, lo); + } + *pivot = *mid; + pivot = &pivot_buffer; + } + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) (*left_ptr, *pivot) < 0) + left_ptr += 1; + + while ((*cmp) (*pivot, *right_ptr) < 0) + right_ptr -= 1; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr); + left_ptr += 1; + right_ptr -= 1; + } + else if (left_ptr == right_ptr) + { + left_ptr += 1; + right_ptr -= 1; + break; + } + } + while (left_ptr <= right_ptr); + + } + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((right_ptr - lo) <= max_thresh) + { + if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ + POP (lo, hi); + else /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */ + { + PUSH (lo, right_ptr); + lo = left_ptr; + } + else /* Push larger right partition indices. */ + { + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + + { + *end_ptr = base_ptr + 1 * (total_elems - 1); + *run_ptr; + *tmp_ptr = base_ptr; + *thresh = (end_ptr < (base_ptr + max_thresh))? + end_ptr : (base_ptr + max_thresh); + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr += 1) + if ((*cmp) (*run_ptr, *tmp_ptr) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr); + + /* Insertion sort, running from left-hand-side up to `right-hand-side.' + Pretty much straight out of the original GNU qsort routine. */ + + for (run_ptr = base_ptr + 1; (tmp_ptr = run_ptr += 1) <= end_ptr; ) + { + + while ((*cmp) (*run_ptr, *(tmp_ptr -= 1)) < 0) + ; + + if ((tmp_ptr += 1) != run_ptr) + { + *trav; + + for (trav = run_ptr + 1; --trav >= run_ptr;) + { + c = *trav; + *hi, *lo; + + for (hi = lo = trav; (lo -= 1) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + + } + } + return 1; +} diff --git a/gnu/lib/libg++/g++-include/gen/Vec.hP b/gnu/lib/libg++/g++-include/gen/Vec.hP new file mode 100644 index 0000000000..97ff3f5fef --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Vec.hP @@ -0,0 +1,135 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _Vec_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Vec_h 1 + +#include +#include ".defs.h" + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)(); +typedef (*Mapper)(); +typedef (*Combiner)(, ); +typedef int (*Predicate)(); +typedef int (*Comparator)(, ); +#endif + + +class Vec +{ +protected: + int len; + *s; + + Vec(int l, * d); +public: + Vec (); + Vec (int l); + Vec (int l, fill_value); + Vec (Vec&); + ~Vec (); + + Vec & operator = (Vec & a); + Vec at(int from = 0, int n = -1); + + int capacity(); + void resize(int newlen); + + & operator [] (int n); + & elem(int n); + + friend Vec concat(Vec & a, Vec & b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec & a); + + void reverse(); + void sort(Comparator f); + void fill( val, int from = 0, int n = -1); + + void apply(Procedure f); + reduce(Combiner f, base); + int index( targ); + + friend int operator == (Vec& a, Vec& b); + friend int operator != (Vec& a, Vec& b); + + void error(const char* msg); + void range_error(); +}; + +extern void default_Vec_error_handler(const char*); +extern one_arg_error_handler_t Vec_error_handler; + +extern one_arg_error_handler_t + set_Vec_error_handler(one_arg_error_handler_t f); + + +inline Vec::Vec() +{ + len = 0; s = 0; +} + +inline Vec::Vec(int l) +{ + s = new [len = l]; +} + + +inline Vec::Vec(int l, * d) :len(l), s(d) {} + + +inline Vec::~Vec() +{ + delete [] s; +} + + +inline & Vec::operator [] (int n) +{ + if ((unsigned)n >= (unsigned)len) + range_error(); + return s[n]; +} + +inline & Vec::elem(int n) +{ + return s[n]; +} + + +inline int Vec::capacity() +{ + return len; +} + + + +inline int operator != (Vec& a, Vec& b) +{ + return !(a == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPBag.ccP b/gnu/lib/libg++/g++-include/gen/XPBag.ccP new file mode 100644 index 0000000000..76dc35cf39 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPBag.ccP @@ -0,0 +1,72 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPBag.h" + +int XPBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPBag::seek( item, Pix i) +{ + if (i == 0) i = p.first(); else next(i); + for (; i != 0; p.next(i)) if (EQ(p(i), item)) return i; + return 0; +} + +int XPBag::nof( item) +{ + int n = 0; + for (int i = p.low(); i < p.fence(); p.next(i)) if (EQ(p[i], item)) ++n; + return n; +} + +void XPBag::del( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + return; + } + } +} + +void XPBag::remove( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/XPBag.hP b/gnu/lib/libg++/g++-include/gen/XPBag.hP new file mode 100644 index 0000000000..296a59082d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPBag.hP @@ -0,0 +1,98 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPBag_h 1 + +#include ".Bag.h" +#include ".XPlex.h" + +class XPBag : public Bag +{ +protected: + XPlex p; + +public: + XPBag(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPBag(const XPBag&); + + Pix add( item); + void del( item); +#undef remove + void remove(item); + int nof( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item, Pix from = 0); + + int OK(); +}; + + +inline XPBag::XPBag(int chunksize) + : p(chunksize) { count = 0; } + +inline XPBag::XPBag(const XPBag& s) : p(s.p) { count = s.count; } + +inline Pix XPBag::first() +{ + return p.first(); +} + +inline void XPBag::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void XPBag::clear() +{ + count = 0; p.clear(); +} + +inline int XPBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline Pix XPBag::add( item) +{ + ++count; + return p.index_to_Pix(p.add_high(item)); +} + +inline int XPBag::contains( item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPDeque.ccP b/gnu/lib/libg++/g++-include/gen/XPDeque.ccP new file mode 100644 index 0000000000..6b363d9bdc --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPDeque.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPDeque.h" diff --git a/gnu/lib/libg++/g++-include/gen/XPDeque.hP b/gnu/lib/libg++/g++-include/gen/XPDeque.hP new file mode 100644 index 0000000000..b8e7c8268f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPDeque.hP @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPDeque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPDeque_h + +#include ".XPlex.h" +#include ".Deque.h" + +class XPDeque : public Deque +{ + XPlex p; + +public: + XPDeque(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPDeque(const XPDeque& d); + ~XPDeque(); + + void operator = (const XPDeque&); + + void push( item); // insert at front + void enq( item); // insert at rear + + & front(); + & rear(); + + deq(); + void del_front(); + void del_rear(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline XPDeque::XPDeque(int chunksize) + : p(chunksize) {} +inline XPDeque::XPDeque(const XPDeque& d) : p(d.p) {} + +inline XPDeque::~XPDeque() {} + +inline void XPDeque::push(item) +{ + p.add_low(item); +} + +inline void XPDeque::enq(item) +{ + p.add_high(item); +} + +inline XPDeque::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & XPDeque::front() +{ + return p.low_element(); +} + +inline & XPDeque::rear() +{ + return p.high_element(); +} + +inline void XPDeque::del_front() +{ + p.del_low(); +} + +inline void XPDeque::del_rear() +{ + p.del_high(); +} + +inline void XPDeque::operator =(const XPDeque& s) +{ + p.operator = (s.p); +} + + +inline int XPDeque::empty() +{ + return p.empty(); +} + +inline int XPDeque::full() +{ + return p.full(); +} + +inline int XPDeque::length() +{ + return p.length(); +} + +inline int XPDeque::OK() +{ + return p.OK(); +} + +inline void XPDeque::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPPQ.ccP b/gnu/lib/libg++/g++-include/gen/XPPQ.ccP new file mode 100644 index 0000000000..41515a39bb --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPPQ.ccP @@ -0,0 +1,143 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPPQ.h" + +int XPPQ::OK() +{ + int v = p.OK(); + v &= p.low() == 1; + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPPQ::seek( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + if (EQ(p[i],item)) return p.index_to_Pix(i); + return 0; +} + +// standard 2-ary heap ops +// pointers are used a lot to avoid thrashing across chunks with plexes + +Pix XPPQ::enq( item) +{ + p.add_high(item); + * pk = &(p.high_element()); + int par = ++count >> 1; + while (par != 0) + { + * ppar = &(p[par]); + if (!(LE(*ppar, item))) + { + *pk = *ppar; + pk = ppar; + par >>= 1; + } + else + break; + } + *pk = item; + return Pix(pk); +} + +void XPPQ::del_front() +{ + if (count == 0) error("empty PQ"); + --count; + * pk = &(p.low_element()); + * ph = &(p.high_element()); + int child = 2; + while (child <= count) + { + * pchild = &(p[child]); + if (child < count) + { + * prchild = &(p[child+1]); + if (!(LE(*pchild, *prchild))) + { + pchild = prchild; + ++child; + } + } + if (!(LE(*ph, *pchild))) + { + *pk = *pchild; + pk = pchild; + child <<= 1; + } + else + break; + } + *pk = *ph; + p.del_high(); +} + + +void XPPQ::del(Pix i) +{ + if (i == 0) error("null Pix"); + --count; + int k = p.Pix_to_index(i); + * pk = &(p[k]); + * ph = &(p.high_element()); + int child = k << 1; + while (child <= count) + { + * pchild = &(p[child]); + if (child < count) + { + * prchild = &(p[child+1]); + if (!(LE(*pchild, *prchild))) + { + pchild = prchild; + ++child; + } + } + if (!(LE(*ph, *pchild))) + { + *pk = *pchild; + pk = pchild; + child <<= 1; + } + else + break; + } + int par = child >> 2; + while (par != 0) + { + * ppar = &(p[par]); + if (!(LE(*ppar, *ph))) + { + *pk = *ppar; + pk = ppar; + par >>= 1; + } + else + break; + } + *pk = *ph; + p.del_high(); +} + + diff --git a/gnu/lib/libg++/g++-include/gen/XPPQ.hP b/gnu/lib/libg++/g++-include/gen/XPPQ.hP new file mode 100644 index 0000000000..af813a2b90 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPPQ.hP @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPPQ_h 1 + +#include ".PQ.h" +#include ".XPlex.h" + +class XPPQ : public PQ +{ +protected: + XPlex p; + +public: + XPPQ(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPPQ(const XPPQ&); + + Pix enq( item); + deq(); + + & front(); + void del_front(); + + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + void del(Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); // rep invariant +}; + +inline XPPQ::XPPQ(int chunksize) + : p(1, chunksize) { count = 0; } + +inline XPPQ::XPPQ(const XPPQ& s) : p(s.p) { count = s.count; } + +inline Pix XPPQ::first() +{ + return p.first(); +} + +inline void XPPQ::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPPQ::operator ()(Pix idx) +{ + return p(idx); +} + +inline & XPPQ::front () +{ + return p.low_element(); +} + +inline XPPQ::deq () +{ + x = p.low_element(); + del_front(); + return x; +} + +inline void XPPQ::clear() +{ + count = 0; p.clear(); +} + +inline int XPPQ::contains ( item) +{ + return seek(item) != 0; +} + +inline int XPPQ::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPQueue.ccP b/gnu/lib/libg++/g++-include/gen/XPQueue.ccP new file mode 100644 index 0000000000..77bfd1c7a9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPQueue.h" diff --git a/gnu/lib/libg++/g++-include/gen/XPQueue.hP b/gnu/lib/libg++/g++-include/gen/XPQueue.hP new file mode 100644 index 0000000000..ebae20f3f6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPQueue.hP @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPQueue_h + +#include ".XPlex.h" +#include ".Queue.h" + +class XPQueue : public Queue +{ +protected: + XPlex p; + +public: + XPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPQueue(const XPQueue& q); + ~XPQueue(); + + void operator = (const XPQueue&); + + void enq( item); + deq(); + & front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline XPQueue::XPQueue(int chunksize) + : p(chunksize) {} +inline XPQueue::XPQueue(const XPQueue& q) : p(q.p) {} + +inline XPQueue::~XPQueue() {} + +inline void XPQueue::enq(item) +{ + p.add_high(item); +} + +inline XPQueue::deq() +{ + res = p.low_element(); + p.del_low(); + return res; +} + +inline & XPQueue::front() +{ + return p.low_element(); +} + + +inline void XPQueue::del_front() +{ + p.del_low(); +} + +inline void XPQueue::operator =(const XPQueue& s) +{ + p.operator = (s.p); +} + +inline int XPQueue::empty() +{ + return p.empty(); +} + +inline int XPQueue::full() +{ + return p.full(); +} + +inline int XPQueue::length() +{ + return p.length(); +} + +inline int XPQueue::OK() +{ + return p.OK(); +} + +inline void XPQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPSet.ccP b/gnu/lib/libg++/g++-include/gen/XPSet.ccP new file mode 100644 index 0000000000..1102790700 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPSet.ccP @@ -0,0 +1,63 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPSet.h" + +int XPSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix XPSet::seek( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + if (EQ(p[i],item)) return p.index_to_Pix(i); + return 0; +} + +Pix XPSet::add( item) +{ + Pix i = seek(item); + if (i == 0) + { + ++count; + i = p.index_to_Pix(p.add_high(item)); + } + return i; +} + +void XPSet::del( item) +{ + for (int i = p.low(); i < p.fence(); p.next(i)) + { + if (EQ(p[i], item)) + { + --count; + p[i] = p.low_element(); + p.del_low(); + return; + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/XPSet.hP b/gnu/lib/libg++/g++-include/gen/XPSet.hP new file mode 100644 index 0000000000..9269ec12c8 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPSet.hP @@ -0,0 +1,89 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPSet_h 1 + +#include ".Set.h" +#include ".XPlex.h" + +class XPSet : public Set +{ +protected: + XPlex p; + +public: + XPSet(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPSet(const XPSet&); + + Pix add( item); + void del( item); + int contains( item); + + void clear(); + + Pix first(); + void next(Pix& i); + & operator () (Pix i); + int owns(Pix i); + Pix seek( item); + + int OK(); +}; + + +inline XPSet::XPSet(int chunksize) + : p(chunksize) { count = 0; } + +inline XPSet::XPSet(const XPSet& s) : p(s.p) { count = s.count; } + +inline Pix XPSet::first() +{ + return p.first(); +} + +inline void XPSet::next(Pix & idx) +{ + p.next(idx); +} + +inline & XPSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void XPSet::clear() +{ + count = 0; p.clear(); +} + +inline int XPSet::contains ( item) +{ + return seek(item) != 0; +} + +inline int XPSet::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPStack.ccP b/gnu/lib/libg++/g++-include/gen/XPStack.ccP new file mode 100644 index 0000000000..fe24f0f044 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPStack.h" diff --git a/gnu/lib/libg++/g++-include/gen/XPStack.hP b/gnu/lib/libg++/g++-include/gen/XPStack.hP new file mode 100644 index 0000000000..9d103e530d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPStack.hP @@ -0,0 +1,115 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _XPStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPStack_h + +#include ".XPlex.h" +#include ".Stack.h" + +class XPStack : public Stack +{ + XPlex p; + +public: + XPStack(int chunksize = DEFAULT_INITIAL_CAPACITY); + XPStack(const XPStack& s); + ~XPStack(); + + void operator = (const XPStack&); + + void push( item); + pop(); + & top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + + +inline XPStack::XPStack(int chunksize) + : p(chunksize) {} +inline XPStack::XPStack(const XPStack& s) : p(s.p) {} + +inline XPStack::~XPStack() {} + +inline void XPStack::push(item) +{ + p.add_high(item); +} + +inline XPStack::pop() +{ + res = p.high_element(); + p.del_high(); + return res; +} + +inline & XPStack::top() +{ + return p.high_element(); +} + +inline void XPStack::del_top() +{ + p.del_high(); +} + +inline void XPStack::operator =(const XPStack& s) +{ + p.operator = (s.p); +} + +inline int XPStack::empty() +{ + return p.empty(); +} + +inline int XPStack::full() +{ + return p.full(); +} + +inline int XPStack::length() +{ + return p.length(); +} + +inline int XPStack::OK() +{ + return p.OK(); +} + +inline void XPStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/XPlex.ccP b/gnu/lib/libg++/g++-include/gen/XPlex.ccP new file mode 100644 index 0000000000..c91e5035a4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPlex.ccP @@ -0,0 +1,397 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include ".XPlex.h" + + +XPlex:: XPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; +} + +XPlex:: XPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize, lo, fnc, fnc)); + hd = ch; + } +} + + +XPlex:: XPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + * data = new [csize]; + set_cache(new IChunk(data, lo, lo, fnc, csize+lo)); + hd = ch; + } + else + { + csize = -chunksize; + * data = new [csize]; + set_cache(new IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } +} + +void XPlex::make_initial_chunks(int up) +{ + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + * data = new [csize]; + IChunk* h = new IChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + set_cache(hd); +} + +XPlex:: XPlex(int l, int hi, const initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + fill(initval); +} + +XPlex::XPlex(const XPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void XPlex::operator= (const XPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void XPlex::cache(int idx) const +{ + const IChunk* tail = tl(); + const IChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) index_error(); + t = (t->next()); + } + while (idx < t->low_index()) + { + if (t == hd) index_error(); + t = (t->prev()); + } + set_cache(t); +} + + +void XPlex::cache(const * p) const +{ + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) index_error(); + } + set_cache(t); +} + +int XPlex::owns(Pix px) const +{ + * p = (*)px; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) { set_cache(t); return 0; } + } + set_cache(t); + return 1; +} + + +* XPlex::dosucc(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + int i = t->index_of(p) + 1; + if (i >= fnc) return 0; + if (i >= t->fence_index()) t = (t->next()); + set_cache(t); + return (t->pointer_to(i)); +} + +* XPlex::dopred(const * p) const +{ + if (p == 0) return 0; + const IChunk* old = ch; + const IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->prev()); + if (t == old) return 0; + } + int i = t->index_of(p) - 1; + if (i < lo) return 0; + if (i < t->low_index()) t = (t->prev()); + set_cache(t); + return (t->pointer_to(i)); +} + + +int XPlex::add_high(const elem) +{ + IChunk* t = tl(); + if (!t->can_grow_high()) + { + if (t->IChunk::empty() && one_chunk()) + t->clear(fnc); + else + { + * data = new [csize]; + t = (new IChunk(data, fnc, fnc, fnc,fnc+csize)); + t->link_to_prev(tl()); + } + } + *((t->IChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int XPlex::del_high () +{ + if (empty()) empty_error(); + IChunk* t = tl(); + t->IChunk::shrink_high(); + if (t->IChunk::empty() && !one_chunk()) + { + IChunk* pred = t->prev(); + del_chunk(t); + t = pred; + } + set_cache(t); + return --fnc - 1; +} + +int XPlex::add_low (const elem) +{ + IChunk* t = hd; + if (!t->can_grow_low()) + { + if (t->IChunk::empty() && one_chunk()) + t->cleardown(lo); + else + { + * data = new [csize]; + hd = new IChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = hd; + } + } + *((t->IChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + + +int XPlex::del_low () +{ + if (empty()) empty_error(); + IChunk* t = hd; + t->IChunk::shrink_low(); + if (t->IChunk::empty() && !one_chunk()) + { + hd = t->next(); + del_chunk(t); + t = hd; + } + set_cache(t); + return ++lo; +} + +void XPlex::reverse() +{ + tmp; + int l = lo; + int h = fnc - 1; + IChunk* loch = hd; + IChunk* hich = tl(); + while (l < h) + { + * lptr = loch->pointer_to(l); + * hptr = hich->pointer_to(h); + tmp = *lptr; + *lptr = *hptr; + *hptr = tmp; + if (++l >= loch->fence_index()) loch = loch->next(); + if (--h < hich->low_index()) hich = hich->prev(); + } +} + +void XPlex::fill(const x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void XPlex::fill(const x, int l, int hi) +{ + for (int i = l; i <= hi; ++i) (*this)[i] = x; +} + + +void XPlex::clear() +{ + if (fnc != lo) + { + IChunk* t = tl(); + while (t != hd) + { + IChunk* prv = t->prev(); + del_chunk(t); + t = prv; + } + t->IChunk::clear(lo); + set_cache(t); + fnc = lo; + } +} + + +int XPlex::OK () const +{ + int v = hd != 0 && ch != 0; // at least one chunk + + v &= fnc == tl()->fence_index();// last chunk fence == plex fence + v &= lo == ((hd))->IChunk::low_index(); // first lo == plex lo + +// loop for others: + int found_ch = 0; // to make sure ch is in list; + const IChunk* t = (hd); + for (;;) + { + if (t == ch) ++found_ch; + v &= t->IChunk::OK(); // each chunk is OK + if (t == tl()) + break; + else // and has indices contiguous to succ + { + v &= t->top_index() == t->next()->base_index(); + if (t != hd) // internal chunks full + { + v &= !t->empty(); + v &= !t->can_grow_low(); + v &= !t->can_grow_high(); + } + t = t->next(); + } + } + v &= found_ch == 1; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/XPlex.hP b/gnu/lib/libg++/g++-include/gen/XPlex.hP new file mode 100644 index 0000000000..41f100091b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/XPlex.hP @@ -0,0 +1,238 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _XPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _XPlex_h 1 + +#include ".Plex.h" + +class XPlex: public Plex +{ + IChunk* ch; // cached chunk + + void make_initial_chunks(int up = 1); + + void cache(int idx) const; + void cache(const * p) const; + + * dopred(const * p) const; + * dosucc(const * p) const; + + void set_cache(const IChunk* t) const; // logically, + // not physically const +public: + XPlex(); // set low = 0; + // fence = 0; + // csize = default + + XPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + XPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + XPlex(int lo, // low = lo + int hi, // fence = hi+1 + const initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + XPlex(const XPlex&); + + void operator= (const XPlex&); + +// virtuals + + + & high_element (); + & low_element (); + + const & high_element () const; + const & low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + & operator () (Pix p); + const & operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + & operator [] (int index); + const & operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const elem); + int del_high (); + int add_low (const elem); + int del_low (); + + void fill(const x); + void fill(const x, int from, int to); + void clear(); + void reverse(); + + int OK () const; + +}; + + +inline void XPlex::prev(int& idx) const +{ + --idx; +} + +inline void XPlex::next(int& idx) const +{ + ++idx; +} + +inline int XPlex::full () const +{ + return 0; +} + +inline int XPlex::can_add_high() const +{ + return 1; +} + +inline int XPlex::can_add_low() const +{ + return 1; +} + +inline int XPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int XPlex::low() const +{ + return lo; +} + +inline int XPlex::high() const +{ + return fnc - 1; +} + +inline & XPlex:: operator [] (int idx) +{ + if (!ch->actual_index(idx)) cache(idx); + return *(ch->pointer_to(idx)); +} + +inline const & XPlex:: operator [] (int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return *((const *)(ch->pointer_to(idx))); +} + +inline & XPlex::low_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline const & XPlex::low_element () const +{ + if (empty()) index_error(); + return *((const *)(hd->pointer_to(lo))); +} + +inline & XPlex::high_element () +{ + if (empty()) index_error(); + return *(tl()->pointer_to(fnc - 1)); +} + +inline const & XPlex::high_element () const +{ + if (empty()) index_error(); + return *((const *)(tl()->pointer_to(fnc - 1))); +} + +inline int XPlex::Pix_to_index(Pix px) const +{ + * p = (*)px; + if (!ch->actual_pointer(p)) cache(p); + return ch->index_of(p); +} + +inline Pix XPlex::index_to_Pix(int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return (Pix)(ch->pointer_to(idx)); +} + +inline Pix XPlex::first() const +{ + return Pix(hd->IChunk::first_pointer()); +} + +inline Pix XPlex::last() const +{ + return Pix(tl()->IChunk::last_pointer()); +} + +inline void XPlex::prev(Pix& p) const +{ + Pix q = Pix(ch->IChunk::pred((*) p)); + p = (q == 0)? Pix(dopred((const *) p)) : q; +} + +inline void XPlex::next(Pix& p) const +{ + Pix q = Pix(ch->IChunk::succ((*) p)); + p = (q == 0)? Pix(dosucc((const *)p)) : q; +} + +inline & XPlex:: operator () (Pix p) +{ + return *((*)p); +} + +inline const & XPlex:: operator () (Pix p) const +{ + return *((const *)p); +} + +inline void XPlex::set_cache(const IChunk* t) const +{ + ((XPlex*)(this))->ch = (IChunk*)t; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/defs.hP b/gnu/lib/libg++/g++-include/gen/defs.hP new file mode 100644 index 0000000000..054f6a65c3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/defs.hP @@ -0,0 +1,57 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _defs_h +#define _defs_h 1 + + +// equality operator +#ifndef EQ +#define EQ(a, b) ((a) == (b)) +#endif + +// less-than-or-equal +#ifndef LE +#define LE(a, b) ((a) <= (b)) +#endif + +// comparison : less-than -> < 0; equal -> 0; greater-than -> > 0 +#ifndef CMP +#define CMP(a, b) ( ((a) <= (b))? (((a) == (b))? 0 : -1) : 1 ) +#endif + +// hash function +#ifndef HASH +extern unsigned int hash(); +#define HASH(x) hash(x) +#endif + +// initial capacity for structures requiring one + +#ifndef DEFAULT_INITIAL_CAPACITY +#define DEFAULT_INITIAL_CAPACITY 100 +#endif + +// HASHTABLE_TOO_CROWDED(COUNT, SIZE) is true iff a hash table with COUNT +// elements and SIZE slots is too full, and should be resized. +// This is so if available space is less than 1/8. + +#define HASHTABLE_TOO_CROWDED(COUNT, SIZE) ((SIZE) - ((SIZE) >> 3) <= (COUNT)) + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/intSList.hP b/gnu/lib/libg++/g++-include/gen/intSList.hP new file mode 100644 index 0000000000..24aa3b6a68 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/intSList.hP @@ -0,0 +1,33 @@ +/* : Light weight List: This will simply reuse code from a int List, which +was genclassed from the SLList libg++ class. The classes generated from this file +will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not +offer all the functionality of List classes, such as sharing of sub-Lists. +However, no additional code is needed at all and no .cc file is generated. So it costs nothing +to use these type-safe Lists. Only member functions needing type casting are re-defined */ + + +#ifndef _SList_h +#define _SList_h 1 + +#include "int.SLList.h" +#include ".defs.h" + +class SList : public intSLList +{ +public: + SList() {} + SList(SList& a) : (a) {} + ~SList() {} + + SList& operator = (SList& a) { + return (SList&) intSLList::operator= (a); } + + & operator () (Pix p) { return (&) (intSLList::operator() (p)); } + & front() { return (&) intSLList::front(); } + & rear() { return (&) intSLList::rear(); } + remove_front() { return () intSLList::remove_front(); } + +}; + +#endif /* conditional include */ + diff --git a/gnu/lib/libg++/g++-include/gen/intVec.hP b/gnu/lib/libg++/g++-include/gen/intVec.hP new file mode 100644 index 0000000000..e383870025 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/intVec.hP @@ -0,0 +1,80 @@ +/* : light weight Vector: This will simply reuse code from */ +/* a int Vec, which was genclassed from the Vec libg++ class. */ +/* The classes generated from this file will all be derived classes */ +/* from class VoidVec or intVec. No .cc file is generated. So */ +/* it costs nothing to use these type-safe Vectors. Only member */ +/* functions needing type casting are re-defined. */ +/* */ + +#ifndef _Vec_h +#define _Vec_h 1 + +#include "int.Vec.h" +#include ".defs.h" + + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)( ); +typedef (*Mapper)( ); +typedef (*Combiner)( , ); +typedef int (*Predicate)( ); +typedef int (*Comparator)( , ); +#endif + +class Vec : public intVec +{ +protected: + Vec(int l, * d) : (l, (int*) d) {}; +public: + Vec() {}; + Vec(int l) : (l) {}; + Vec(int l, fill_value) : (l, fill_value) {}; + Vec(Vec& v) : (v) {}; + Vec(intVec& v) {fake_copy(v, s, len);} + ~Vec() {}; + + Vec& operator = (Vec& a) + {return (Vec&) intVec::operator= (a);} + Vec at(int from, int n) {return (Vec) intVec::at(from, n);} + + & operator [] (int n) {return (&)intVec::operator[] (n);} + & elem(int n) {return (&)intVec::elem(n);} + + friend Vec concat(Vec& a, Vec& b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec& a); + + void sort(Comparator f); + void apply(Procedure f); + reduce(Combiner f, base); +}; + +inline Vec concat(Vec& a, Vec& b) +{return (Vec)concat((intVec&)a, (intVec&)b);} + +inline Vec map(Mapper f, Vec & a) { + return (Vec)map((intMapper)f, (intVec&)a); } + +inline Vec merge(Vec & a, Vec & b, Comparator f) { + return (Vec)merge((intVec&)a, (intVec&)b, (intComparator)f); } + +inline Vec combine(Combiner f, Vec & a, Vec & b) { + return (Vec)combine((intCombiner)f, (intVec&)a, (intVec&)b); } + +inline Vec reverse(Vec& a) { + return (Vec)reverse((intVec&)a);} + +inline void Vec::sort(Comparator f) { + intVec::sort((intComparator) f); } + +inline void Vec::apply(Procedure f) { + intVec::apply((intProcedure) f); } + +inline Vec::reduce(Combiner f, base) { + return ()intVec::reduce((intCombiner)f, base);} + +#endif /* conditional include */ + diff --git a/gnu/lib/libg++/g++-include/intSList.hP b/gnu/lib/libg++/g++-include/intSList.hP new file mode 100644 index 0000000000..24aa3b6a68 --- /dev/null +++ b/gnu/lib/libg++/g++-include/intSList.hP @@ -0,0 +1,33 @@ +/* : Light weight List: This will simply reuse code from a int List, which +was genclassed from the SLList libg++ class. The classes generated from this file +will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not +offer all the functionality of List classes, such as sharing of sub-Lists. +However, no additional code is needed at all and no .cc file is generated. So it costs nothing +to use these type-safe Lists. Only member functions needing type casting are re-defined */ + + +#ifndef _SList_h +#define _SList_h 1 + +#include "int.SLList.h" +#include ".defs.h" + +class SList : public intSLList +{ +public: + SList() {} + SList(SList& a) : (a) {} + ~SList() {} + + SList& operator = (SList& a) { + return (SList&) intSLList::operator= (a); } + + & operator () (Pix p) { return (&) (intSLList::operator() (p)); } + & front() { return (&) intSLList::front(); } + & rear() { return (&) intSLList::rear(); } + remove_front() { return () intSLList::remove_front(); } + +}; + +#endif /* conditional include */ + diff --git a/gnu/lib/libg++/g++-include/intVec.hP b/gnu/lib/libg++/g++-include/intVec.hP new file mode 100644 index 0000000000..e383870025 --- /dev/null +++ b/gnu/lib/libg++/g++-include/intVec.hP @@ -0,0 +1,80 @@ +/* : light weight Vector: This will simply reuse code from */ +/* a int Vec, which was genclassed from the Vec libg++ class. */ +/* The classes generated from this file will all be derived classes */ +/* from class VoidVec or intVec. No .cc file is generated. So */ +/* it costs nothing to use these type-safe Vectors. Only member */ +/* functions needing type casting are re-defined. */ +/* */ + +#ifndef _Vec_h +#define _Vec_h 1 + +#include "int.Vec.h" +#include ".defs.h" + + +#ifndef __typedefs +#define __typedefs 1 +typedef void (*Procedure)( ); +typedef (*Mapper)( ); +typedef (*Combiner)( , ); +typedef int (*Predicate)( ); +typedef int (*Comparator)( , ); +#endif + +class Vec : public intVec +{ +protected: + Vec(int l, * d) : (l, (int*) d) {}; +public: + Vec() {}; + Vec(int l) : (l) {}; + Vec(int l, fill_value) : (l, fill_value) {}; + Vec(Vec& v) : (v) {}; + Vec(intVec& v) {fake_copy(v, s, len);} + ~Vec() {}; + + Vec& operator = (Vec& a) + {return (Vec&) intVec::operator= (a);} + Vec at(int from, int n) {return (Vec) intVec::at(from, n);} + + & operator [] (int n) {return (&)intVec::operator[] (n);} + & elem(int n) {return (&)intVec::elem(n);} + + friend Vec concat(Vec& a, Vec& b); + friend Vec map(Mapper f, Vec & a); + friend Vec merge(Vec & a, Vec & b, Comparator f); + friend Vec combine(Combiner f, Vec & a, Vec & b); + friend Vec reverse(Vec& a); + + void sort(Comparator f); + void apply(Procedure f); + reduce(Combiner f, base); +}; + +inline Vec concat(Vec& a, Vec& b) +{return (Vec)concat((intVec&)a, (intVec&)b);} + +inline Vec map(Mapper f, Vec & a) { + return (Vec)map((intMapper)f, (intVec&)a); } + +inline Vec merge(Vec & a, Vec & b, Comparator f) { + return (Vec)merge((intVec&)a, (intVec&)b, (intComparator)f); } + +inline Vec combine(Combiner f, Vec & a, Vec & b) { + return (Vec)combine((intCombiner)f, (intVec&)a, (intVec&)b); } + +inline Vec reverse(Vec& a) { + return (Vec)reverse((intVec&)a);} + +inline void Vec::sort(Comparator f) { + intVec::sort((intComparator) f); } + +inline void Vec::apply(Procedure f) { + intVec::apply((intProcedure) f); } + +inline Vec::reduce(Combiner f, base) { + return ()intVec::reduce((intCombiner)f, base);} + +#endif /* conditional include */ + diff --git a/gnu/lib/libg++/libg++/Complex.h b/gnu/lib/libg++/libg++/Complex.h index fecc994372..385ea606d7 100644 --- a/gnu/lib/libg++/libg++/Complex.h +++ b/gnu/lib/libg++/libg++/Complex.h @@ -227,6 +227,12 @@ inline Complex operator - (double x, const Complex& y) return Complex(x - y.real(), -y.imag()); } +inline Complex operator * (const Complex& x, const Complex& y) +{ + return Complex(x.real() * y.real() - x.imag() * y.imag(), + x.real() * y.imag() + x.imag() * y.real()); +} + inline Complex operator * (const Complex& x, double y) { return Complex(x.real() * y, x.imag() * y); diff --git a/gnu/lib/libg++/libg++/Incremental.h b/gnu/lib/libg++/libg++/Incremental.h new file mode 100644 index 0000000000..267970a8cf --- /dev/null +++ b/gnu/lib/libg++/libg++/Incremental.h @@ -0,0 +1,12 @@ +#ifndef Incremental_h +#ifdef __GNUG__ +#pragma interface +#endif +#define Incremental_h +#define DECLARE_INIT_FUNCTION(USER_INIT_FUNCTION) \ +static void USER_INIT_FUNCTION (); extern void (*_initfn)(); \ +static struct xyzzy { xyzzy () {_initfn = USER_INIT_FUNCTION;}; \ +~xyzzy () {};} __2xyzzy; +#else +#error Incremental.h was not the first file included in this module +#endif diff --git a/gnu/lib/libg++/libg++/bool.h b/gnu/lib/libg++/libg++/bool.h new file mode 100644 index 0000000000..9f0fd9115a --- /dev/null +++ b/gnu/lib/libg++/libg++/bool.h @@ -0,0 +1,13 @@ +// Defining TRUE and FALSE is usually a Bad Idea, +// because you will probably be inconsistent with anyone +// else who had the same clever idea. +// Therefore: DON'T USE THIS FILE. + +#ifndef _bool_h +#define _bool_h 1 + +#undef FALSE +#undef TRUE +enum bool { FALSE = 0, TRUE = 1 }; + +#endif diff --git a/gnu/lib/libg++/libg++/complex.h b/gnu/lib/libg++/libg++/complex.h new file mode 100644 index 0000000000..afe2c8bcd9 --- /dev/null +++ b/gnu/lib/libg++/libg++/complex.h @@ -0,0 +1,6 @@ +#ifndef _complex_h +#define _complex_h +#define __ATT_complex__ +#include +typedef class Complex complex; +#endif diff --git a/gnu/lib/libg++/libg++/generic.h b/gnu/lib/libg++/libg++/generic.h new file mode 100644 index 0000000000..56d7cfb8d6 --- /dev/null +++ b/gnu/lib/libg++/libg++/generic.h @@ -0,0 +1,54 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef generic_h +#define generic_h 1 + +/* + * See the CPP manual, argument prescan section for explanation + */ + +#define name2(a,b) gEnErIc2(a,b) +#define gEnErIc2(a,b) a ## b + +#define name3(a,b,c) gEnErIc3(a,b,c) +#define gEnErIc3(a,b,c) a ## b ## c + +#define name4(a,b,c,d) gEnErIc4(a,b,c,d) +#define gEnErIc4(a,b,c,d) a ## b ## c ## d + +#define GENERIC_STRING(a) gEnErIcStRiNg(a) +#define gEnErIcStRiNg(a) #a + +#define declare(clas,t) name2(clas,declare)(t) +#define declare2(clas,t1,t2) name2(clas,declare2)(t1,t2) + +#define implement(clas,t) name2(clas,implement)(t) +#define implement2(clas,t1,t2) name2(clas,implement2)(t1,t2) + +//extern genericerror(int,char*); +typedef int (*GPT)(int,char*); + +#define set_handler(gen,type,x) name4(set_,type,gen,_handler)(x) + +#define errorhandler(gen,type) name3(type,gen,handler) + +#define callerror(gen,type,a,b) (*errorhandler(gen,type))(a,b) + + +#endif generic_h diff --git a/gnu/lib/libg++/libg++/getpagesize.h b/gnu/lib/libg++/libg++/getpagesize.h new file mode 100644 index 0000000000..17d84316bd --- /dev/null +++ b/gnu/lib/libg++/libg++/getpagesize.h @@ -0,0 +1,27 @@ +#if defined(BSD) || defined(DGUX) +#ifndef BSD4_1 +#define HAVE_GETPAGESIZE +#endif +#endif + +#ifndef HAVE_GETPAGESIZE + +#include + +#ifdef EXEC_PAGESIZE +#define getpagesize() EXEC_PAGESIZE +#else +#ifdef NBPG +#define getpagesize() NBPG * CLSIZE +#ifndef CLSIZE +#define CLSIZE 1 +#endif /* no CLSIZE */ +#else /* no NBPG */ +#ifdef NBPC +#define getpagesize() NBPC +#endif /* NBPC */ +#endif /* no NBPG */ +#endif /* no EXEC_PAGESIZE */ + +#endif /* not HAVE_GETPAGESIZE */ + diff --git a/gnu/lib/libg++/libg++/libc.h b/gnu/lib/libg++/libg++/libc.h new file mode 100644 index 0000000000..c8b49f26d1 --- /dev/null +++ b/gnu/lib/libg++/libg++/libc.h @@ -0,0 +1 @@ +#include diff --git a/gnu/lib/libg++/libg++/math-68881.h b/gnu/lib/libg++/libg++/math-68881.h new file mode 100644 index 0000000000..02f50a8e1b --- /dev/null +++ b/gnu/lib/libg++/libg++/math-68881.h @@ -0,0 +1,516 @@ +/******************************************************************\ +* * +* last modified: 23 May 1992. * +* * +* Copyright (C) 1989 by Matthew Self. * +* You may freely distribute verbatim copies of this software * +* provided that this copyright notice is retained in all copies. * +* You may distribute modifications to this software under the * +* conditions above if you also clearly note such modifications * +* with their author and date. * +* * +* Note: errno is not set to EDOM when domain errors occur for * +* most of these functions. Rather, it is assumed that the * +* 68881's OPERR exception will be enabled and handled * +* appropriately by the operating system. Similarly, overflow * +* and underflow do not set errno to ERANGE. * +* * +* Send bugs to Matthew Self (self@bayes.arc.nasa.gov). * +* * +\******************************************************************/ + +/* If you find this in GCC, + please send bug reports to bug-gcc@prep.ai.mit.edu. */ + +/* Changed by Richard Stallman: % inserted before a #. + New function `hypot' added. + Nans written in hex to avoid 0rnan. + May 1992, use %! for fpcr register. Break lines before function names. + December 1989, add parens around `&' in pow. + November 1990, added alternate definition of HUGE_VAL for Sun. */ + +#include + +#ifndef HUGE_VAL +#ifdef __sun__ +/* The Sun assembler fails to handle the hex constant in the usual defn. */ +#define HUGE_VAL \ +({ \ + static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \ + u.d; \ +}) +#else +#define HUGE_VAL \ +({ \ + double huge_val; \ + \ + __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \ + : "=f" (huge_val) \ + : /* no inputs */); \ + huge_val; \ +}) +#endif +#endif + +__inline static const double +sin (double x) +{ + double value; + + __asm ("fsin%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +cos (double x) +{ + double value; + + __asm ("fcos%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +tan (double x) +{ + double value; + + __asm ("ftan%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +asin (double x) +{ + double value; + + __asm ("fasin%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +acos (double x) +{ + double value; + + __asm ("facos%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +atan (double x) +{ + double value; + + __asm ("fatan%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +atan2 (double y, double x) +{ + double pi, pi_over_2; + + __asm ("fmovecr%.x %#0,%0" /* extended precision pi */ + : "=f" (pi) + : /* no inputs */ ); + __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */ + : "=f" (pi_over_2) + : "0" (pi)); + if (x > 0) + { + if (y > 0) + { + if (x > y) + return atan (y / x); + else + return pi_over_2 - atan (x / y); + } + else + { + if (x > -y) + return atan (y / x); + else + return - pi_over_2 - atan (x / y); + } + } + else + { + if (y > 0) + { + if (-x > y) + return pi + atan (y / x); + else + return pi_over_2 - atan (x / y); + } + else + { + if (-x > -y) + return - pi + atan (y / x); + else if (y < 0) + return - pi_over_2 - atan (x / y); + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } + } +} + +__inline static const double +sinh (double x) +{ + double value; + + __asm ("fsinh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +cosh (double x) +{ + double value; + + __asm ("fcosh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +tanh (double x) +{ + double value; + + __asm ("ftanh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +atanh (double x) +{ + double value; + + __asm ("fatanh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +exp (double x) +{ + double value; + + __asm ("fetox%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +expm1 (double x) +{ + double value; + + __asm ("fetoxm1%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +log (double x) +{ + double value; + + __asm ("flogn%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +log1p (double x) +{ + double value; + + __asm ("flognp1%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +log10 (double x) +{ + double value; + + __asm ("flog10%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +sqrt (double x) +{ + double value; + + __asm ("fsqrt%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +hypot (const double x, const double y) +{ + return sqrt (x*x + y*y); +} + +__inline static const double +pow (const double x, const double y) +{ + if (x > 0) + return exp (y * log (x)); + else if (x == 0) + { + if (y > 0) + return 0.0; + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } + else + { + double temp; + + __asm ("fintrz%.x %1,%0" + : "=f" (temp) /* integer-valued float */ + : "f" (y)); + if (y == temp) + { + int i = (int) y; + + if ((i & 1) == 0) /* even */ + return exp (y * log (-x)); + else + return - exp (y * log (-x)); + } + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } +} + +__inline static const double +fabs (double x) +{ + double value; + + __asm ("fabs%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double +ceil (double x) +{ + int rounding_mode, round_up; + double value; + + __asm volatile ("fmove%.l %!,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_up = rounding_mode | 0x30; + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (round_up)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double +floor (double x) +{ + int rounding_mode, round_down; + double value; + + __asm volatile ("fmove%.l %!,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_down = (rounding_mode & ~0x10) + | 0x20; + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (round_down)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double +rint (double x) +{ + int rounding_mode, round_nearest; + double value; + + __asm volatile ("fmove%.l %!,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_nearest = rounding_mode & ~0x30; + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (round_nearest)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,%!" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double +fmod (double x, double y) +{ + double value; + + __asm ("fmod%.x %2,%0" + : "=f" (value) + : "0" (x), + "f" (y)); + return value; +} + +__inline static const double +drem (double x, double y) +{ + double value; + + __asm ("frem%.x %2,%0" + : "=f" (value) + : "0" (x), + "f" (y)); + return value; +} + +__inline static const double +scalb (double x, int n) +{ + double value; + + __asm ("fscale%.l %2,%0" + : "=f" (value) + : "0" (x), + "dmi" (n)); + return value; +} + +__inline static double +logb (double x) +{ + double exponent; + + __asm ("fgetexp%.x %1,%0" + : "=f" (exponent) + : "f" (x)); + return exponent; +} + +__inline static const double +ldexp (double x, int n) +{ + double value; + + __asm ("fscale%.l %2,%0" + : "=f" (value) + : "0" (x), + "dmi" (n)); + return value; +} + +__inline static double +frexp (double x, int *exp) +{ + double float_exponent; + int int_exponent; + double mantissa; + + __asm ("fgetexp%.x %1,%0" + : "=f" (float_exponent) /* integer-valued float */ + : "f" (x)); + int_exponent = (int) float_exponent; + __asm ("fgetman%.x %1,%0" + : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */ + : "f" (x)); + if (mantissa != 0) + { + __asm ("fscale%.b %#-1,%0" + : "=f" (mantissa) /* mantissa /= 2.0 */ + : "0" (mantissa)); + int_exponent += 1; + } + *exp = int_exponent; + return mantissa; +} + +__inline static double +modf (double x, double *ip) +{ + double temp; + + __asm ("fintrz%.x %1,%0" + : "=f" (temp) /* integer-valued float */ + : "f" (x)); + *ip = temp; + return x - temp; +} + diff --git a/gnu/lib/libg++/libg++/minmax.h b/gnu/lib/libg++/libg++/minmax.h new file mode 100644 index 0000000000..ae912881e9 --- /dev/null +++ b/gnu/lib/libg++/libg++/minmax.h @@ -0,0 +1,65 @@ +/* +Copyright (C) 1992 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _minmax_h +#ifdef _GNUG_ +#pragma interface +#endif +#define _minmax_h 1 + +#include <_G_config.h> + +inline char min(char a, char b) { return (a < b)?a:b;} +#ifndef _G_BROKEN_SIGNED_CHAR +inline signed char min(signed char a, signed char b) { return (a < b)?a:b;} +#endif +inline unsigned char min(unsigned char a, unsigned char b) {return (a b)?a:b;} +#ifndef _G_BROKEN_SIGNED_CHAR +inline signed char max(signed char a, signed char b) {return (a > b)?a:b;} +#endif +inline unsigned char max(unsigned char a, unsigned char b) {return (a>b)?a:b;} + +inline short max(short a, short b) {return (a > b) ?a:b;} +inline unsigned short max(unsigned short a, unsigned short b) {return (a > b)?a:b;} + +inline int max(int a, int b) {return (a > b)?a:b;} +inline unsigned int max(unsigned int a, unsigned int b) {return (a > b)?a:b;} + +inline long max(long a, long b) {return (a > b)?a:b;} +inline unsigned long max(unsigned long a, unsigned long b) {return (a>b)?a:b;} + +inline float max(float a, float b) {return (a > b)?a:b;} + +inline double max(double a, double b) {return (a > b)?a:b;} + +#endif + diff --git a/gnu/lib/libg++/libg++/strclass.h b/gnu/lib/libg++/libg++/strclass.h new file mode 100644 index 0000000000..57dbcc8cf9 --- /dev/null +++ b/gnu/lib/libg++/libg++/strclass.h @@ -0,0 +1,5 @@ +#ifndef _strclass_h +#define _strclass_h +#include +typedef class String string; +#endif diff --git a/gnu/lib/libg++/libg++/swap.h b/gnu/lib/libg++/libg++/swap.h new file mode 100644 index 0000000000..005cb0e464 --- /dev/null +++ b/gnu/lib/libg++/libg++/swap.h @@ -0,0 +1,3 @@ +/* From Ron Guillmette; apparently needed for Hansen's code */ + +#define swap(a,b) ({ typeof(a) temp = (a); (a) = (b); (b) = temp; }) diff --git a/gnu/lib/libg++/libg++/typemacros.h b/gnu/lib/libg++/libg++/typemacros.h new file mode 100644 index 0000000000..f2bd7877e3 --- /dev/null +++ b/gnu/lib/libg++/libg++/typemacros.h @@ -0,0 +1,8 @@ +#define _T(type) typeof(type) +#define pointer_to(type) _T(_T(type)*) +#define member_of(cls,type) _T(_T(type) cls::) +#define function(res, args) _T(_T(res) args) + +#define _xq_yq(x,y) x ## _ ## y +#define _x_y(x,y) _xq_yq(x,y) +#define _gensym(stem) _x_y(stem, __LINE__) -- 2.20.1