mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*******************************************************************************************[Vec.h]
 | 
						|
Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
 | 
						|
Copyright (c) 2007-2010, 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 Minisat_Vec_h
 | 
						|
#define Minisat_Vec_h
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <limits>
 | 
						|
#include <new>
 | 
						|
 | 
						|
#include "IntTypes.h"
 | 
						|
#include "XAlloc.h"
 | 
						|
 | 
						|
namespace Minisat {
 | 
						|
 | 
						|
//=================================================================================================
 | 
						|
// Automatically resizable arrays
 | 
						|
//
 | 
						|
// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
 | 
						|
 | 
						|
template<class T, class _Size = int>
 | 
						|
class vec {
 | 
						|
public:
 | 
						|
    typedef _Size Size;
 | 
						|
private:
 | 
						|
    T*   data;
 | 
						|
    Size sz;
 | 
						|
    Size cap;
 | 
						|
 | 
						|
    // Don't allow copying (error prone):
 | 
						|
    vec<T>&  operator=(vec<T>& other);
 | 
						|
             vec      (vec<T>& other);
 | 
						|
 | 
						|
    static inline Size max(Size x, Size y){ return (x > y) ? x : y; }
 | 
						|
 | 
						|
public:
 | 
						|
    // Constructors:
 | 
						|
    vec()                        : data(NULL), sz(0), cap(0)    { }
 | 
						|
    explicit vec(Size size)      : data(NULL), sz(0), cap(0)    { growTo(size); }
 | 
						|
    vec(Size size, const T& pad) : data(NULL), sz(0), cap(0)    { growTo(size, pad); }
 | 
						|
   ~vec()                                                       { clear(true); }
 | 
						|
 | 
						|
    // Pointer to first element:
 | 
						|
    operator T*       (void)           { return data; }
 | 
						|
 | 
						|
    // Size operations:
 | 
						|
    Size     size     (void) const   { return sz; }
 | 
						|
    void     shrink   (Size nelems)  { assert(nelems <= sz); for (Size i = 0; i < nelems; i++) sz--, data[sz].~T(); }
 | 
						|
    void     shrink_  (Size nelems)  { assert(nelems <= sz); sz -= nelems; }
 | 
						|
    int      capacity (void) const   { return cap; }
 | 
						|
    void     capacity (Size min_cap);
 | 
						|
    void     growTo   (Size size);
 | 
						|
    void     growTo   (Size size, const T& pad);
 | 
						|
    void     clear    (bool dealloc = false);
 | 
						|
 | 
						|
    // Stack interface:
 | 
						|
    void     push  (void)              { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
 | 
						|
    //void     push  (const T& elem)     { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
 | 
						|
    void     push  (const T& elem)     { if (sz == cap) capacity(sz+1); new (&data[sz++]) T(elem); }
 | 
						|
    void     push_ (const T& elem)     { assert(sz < cap); data[sz++] = elem; }
 | 
						|
    void     pop   (void)              { assert(sz > 0); sz--, data[sz].~T(); }
 | 
						|
    // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
 | 
						|
    // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
 | 
						|
    // happen given the way capacities are calculated (below). Essentially, all capacities are
 | 
						|
    // even, but INT_MAX is odd.
 | 
						|
 | 
						|
    const T& last  (void) const        { return data[sz-1]; }
 | 
						|
    T&       last  (void)              { return data[sz-1]; }
 | 
						|
 | 
						|
    // Vector interface:
 | 
						|
    const T& operator [] (Size index) const { return data[index]; }
 | 
						|
    T&       operator [] (Size index)       { return data[index]; }
 | 
						|
 | 
						|
    // Duplicatation (preferred instead):
 | 
						|
    void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (Size i = 0; i < sz; i++) copy[i] = data[i]; }
 | 
						|
    void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
template<class T, class _Size>
 | 
						|
void vec<T,_Size>::capacity(Size min_cap) {
 | 
						|
    if (cap >= min_cap) return;
 | 
						|
    Size add = max((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1);   // NOTE: grow by approximately 3/2
 | 
						|
    const Size size_max = std::numeric_limits<Size>::max();
 | 
						|
    if ( ((size_max <= std::numeric_limits<int>::max()) && (add > size_max - cap))
 | 
						|
    ||   (
 | 
						|
#ifdef _DEFAULT_SOURCE
 | 
						|
            ((data = (T*)::reallocarray(data, (cap += add), sizeof(T))) == NULL)
 | 
						|
#else
 | 
						|
            ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) 
 | 
						|
#endif
 | 
						|
	&& errno == ENOMEM) )
 | 
						|
        throw OutOfMemoryException();
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
template<class T, class _Size>
 | 
						|
void vec<T,_Size>::growTo(Size size, const T& pad) {
 | 
						|
    if (sz >= size) return;
 | 
						|
    capacity(size);
 | 
						|
    for (Size i = sz; i < size; i++) data[i] = pad;
 | 
						|
    sz = size; }
 | 
						|
 | 
						|
 | 
						|
template<class T, class _Size>
 | 
						|
void vec<T,_Size>::growTo(Size size) {
 | 
						|
    if (sz >= size) return;
 | 
						|
    capacity(size);
 | 
						|
    for (Size i = sz; i < size; i++) new (&data[i]) T();
 | 
						|
    sz = size; }
 | 
						|
 | 
						|
 | 
						|
template<class T, class _Size>
 | 
						|
void vec<T,_Size>::clear(bool dealloc) {
 | 
						|
    if (data != NULL){
 | 
						|
        for (Size i = 0; i < sz; i++) data[i].~T();
 | 
						|
        sz = 0;
 | 
						|
        if (dealloc) free(data), data = NULL, cap = 0; } }
 | 
						|
 | 
						|
//=================================================================================================
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |