148 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			148 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*******************************************************************************************[Vec.h]
							 | 
						||
| 
								 | 
							
								MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
							 | 
						||
| 
								 | 
							
								associated documentation files (the "Software"), to deal in the Software without restriction,
							 | 
						||
| 
								 | 
							
								including without limitation the rights to use, copy, modify, merge, publish, distribute,
							 | 
						||
| 
								 | 
							
								sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
							 | 
						||
| 
								 | 
							
								furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The above copyright notice and this permission notice shall be included in all copies or
							 | 
						||
| 
								 | 
							
								substantial portions of the Software.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
							 | 
						||
| 
								 | 
							
								NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
							 | 
						||
| 
								 | 
							
								NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
							 | 
						||
| 
								 | 
							
								DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
							 | 
						||
| 
								 | 
							
								OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
							 | 
						||
| 
								 | 
							
								**************************************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BoxedVec_h
							 | 
						||
| 
								 | 
							
								#define BoxedVec_h
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <cstdlib>
							 | 
						||
| 
								 | 
							
								#include <cassert>
							 | 
						||
| 
								 | 
							
								#include <new>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//=================================================================================================
							 | 
						||
| 
								 | 
							
								// Automatically resizable arrays
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class T>
							 | 
						||
| 
								 | 
							
								class bvec {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static inline int imin(int x, int y) {
							 | 
						||
| 
								 | 
							
								        int mask = (x-y) >> (sizeof(int)*8-1);
							 | 
						||
| 
								 | 
							
								        return (x&mask) + (y&(~mask)); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static inline int imax(int x, int y) {
							 | 
						||
| 
								 | 
							
								        int mask = (y-x) >> (sizeof(int)*8-1);
							 | 
						||
| 
								 | 
							
								        return (x&mask) + (y&(~mask)); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct Vec_t {
							 | 
						||
| 
								 | 
							
								        int sz;
							 | 
						||
| 
								 | 
							
								        int cap;
							 | 
						||
| 
								 | 
							
								        T   data[0];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static Vec_t* alloc(Vec_t* x, int size){
							 | 
						||
| 
								 | 
							
								            x = (Vec_t*)realloc((void*)x, sizeof(Vec_t) + sizeof(T)*size);
							 | 
						||
| 
								 | 
							
								            x->cap = size;
							 | 
						||
| 
								 | 
							
								            return x;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Vec_t* ref;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static const int init_size = 2;
							 | 
						||
| 
								 | 
							
								    static int   nextSize (int current) { return (current * 3 + 1) >> 1; }
							 | 
						||
| 
								 | 
							
								    static int   fitSize  (int needed)  { int x; for (x = init_size; needed > x; x = nextSize(x)); return x; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void fill (int size) {
							 | 
						||
| 
								 | 
							
								        assert(ref != NULL);
							 | 
						||
| 
								 | 
							
								        for (T* i = ref->data; i < ref->data + size; i++)
							 | 
						||
| 
								 | 
							
								            new (i) T();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void fill (int size, const T& pad) {
							 | 
						||
| 
								 | 
							
								        assert(ref != NULL);
							 | 
						||
| 
								 | 
							
								        for (T* i = ref->data; i < ref->data + size; i++)
							 | 
						||
| 
								 | 
							
								            new (i) T(pad);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Don't allow copying (error prone):
							 | 
						||
| 
								 | 
							
								    altvec<T>&  operator = (altvec<T>& other) { assert(0); }
							 | 
						||
| 
								 | 
							
								    altvec (altvec<T>& other)                  { assert(0); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    void     clear  (bool dealloc = false) { 
							 | 
						||
| 
								 | 
							
								        if (ref != NULL){
							 | 
						||
| 
								 | 
							
								            for (int i = 0; i < ref->sz; i++) 
							 | 
						||
| 
								 | 
							
								                (*ref).data[i].~T();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (dealloc) { 
							 | 
						||
| 
								 | 
							
								                free(ref); ref = NULL; 
							 | 
						||
| 
								 | 
							
								            }else 
							 | 
						||
| 
								 | 
							
								                ref->sz = 0;
							 | 
						||
| 
								 | 
							
								        } 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Constructors:
							 | 
						||
| 
								 | 
							
								    altvec(void)                   : ref (NULL) { }
							 | 
						||
| 
								 | 
							
								    altvec(int size)               : ref (Vec_t::alloc(NULL, fitSize(size))) { fill(size);      ref->sz = size; }
							 | 
						||
| 
								 | 
							
								    altvec(int size, const T& pad) : ref (Vec_t::alloc(NULL, fitSize(size))) { fill(size, pad); ref->sz = size; }
							 | 
						||
| 
								 | 
							
								   ~altvec(void) { clear(true); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Ownership of underlying array:
							 | 
						||
| 
								 | 
							
								    operator T*       (void)           { return ref->data; }     // (unsafe but convenient)
							 | 
						||
| 
								 | 
							
								    operator const T* (void) const     { return ref->data; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Size operations:
							 | 
						||
| 
								 | 
							
								    int      size   (void) const       { return ref != NULL ? ref->sz : 0; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void     pop    (void)             { assert(ref != NULL && ref->sz > 0); int last = --ref->sz; ref->data[last].~T(); }
							 | 
						||
| 
								 | 
							
								    void     push   (const T& elem) {
							 | 
						||
| 
								 | 
							
								        int size = ref != NULL ? ref->sz  : 0;
							 | 
						||
| 
								 | 
							
								        int cap  = ref != NULL ? ref->cap : 0;
							 | 
						||
| 
								 | 
							
								        if (size == cap){
							 | 
						||
| 
								 | 
							
								            cap = cap != 0 ? nextSize(cap) : init_size;
							 | 
						||
| 
								 | 
							
								            ref = Vec_t::alloc(ref, cap); 
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        //new (&ref->data[size]) T(elem); 
							 | 
						||
| 
								 | 
							
								        ref->data[size] = elem; 
							 | 
						||
| 
								 | 
							
								        ref->sz = size+1; 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void     push   () {
							 | 
						||
| 
								 | 
							
								        int size = ref != NULL ? ref->sz  : 0;
							 | 
						||
| 
								 | 
							
								        int cap  = ref != NULL ? ref->cap : 0;
							 | 
						||
| 
								 | 
							
								        if (size == cap){
							 | 
						||
| 
								 | 
							
								            cap = cap != 0 ? nextSize(cap) : init_size;
							 | 
						||
| 
								 | 
							
								            ref = Vec_t::alloc(ref, cap); 
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        new (&ref->data[size]) T(); 
							 | 
						||
| 
								 | 
							
								        ref->sz = size+1; 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void     shrink (int nelems)             { for (int i = 0; i < nelems; i++) pop(); }
							 | 
						||
| 
								 | 
							
								    void     shrink_(int nelems)             { for (int i = 0; i < nelems; i++) pop(); }
							 | 
						||
| 
								 | 
							
								    void     growTo (int size)               { while (this->size() < size) push(); }
							 | 
						||
| 
								 | 
							
								    void     growTo (int size, const T& pad) { while (this->size() < size) push(pad); }
							 | 
						||
| 
								 | 
							
								    void     capacity (int size)             { growTo(size); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const T& last  (void) const              { return ref->data[ref->sz-1]; }
							 | 
						||
| 
								 | 
							
								    T&       last  (void)                    { return ref->data[ref->sz-1]; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Vector interface:
							 | 
						||
| 
								 | 
							
								    const T& operator [] (int index) const  { return ref->data[index]; }
							 | 
						||
| 
								 | 
							
								    T&       operator [] (int index)        { return ref->data[index]; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void copyTo(altvec<T>& copy) const { copy.clear(); for (int i = 0; i < size(); i++) copy.push(ref->data[i]); }
							 | 
						||
| 
								 | 
							
								    void moveTo(altvec<T>& dest) { dest.clear(true); dest.ref = ref; ref = NULL; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |