/* DB_Row class implementation: inline functions. Copyright (C) 2001-2010 Roberto Bagnara Copyright (C) 2010-2011 BUGSENG srl (http://bugseng.com) This file is part of the Parma Polyhedra Library (PPL). The PPL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The PPL 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. For the most up-to-date information see the Parma Polyhedra Library site: http://www.cs.unipr.it/ppl/ . */ #ifndef PPL_DB_Row_inlines_hh #define PPL_DB_Row_inlines_hh 1 #include "checked.defs.hh" #include "assert.hh" #include #include #include #include namespace Parma_Polyhedra_Library { template inline void* DB_Row_Impl_Handler::Impl::operator new(const size_t fixed_size, const dimension_type capacity) { #if PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS return ::operator new(fixed_size + capacity*sizeof(T)); #else PPL_ASSERT(capacity >= 1); return ::operator new(fixed_size + (capacity-1)*sizeof(T)); #endif } template inline void DB_Row_Impl_Handler::Impl::operator delete(void* p) { ::operator delete(p); } template inline void DB_Row_Impl_Handler::Impl::operator delete(void* p, dimension_type) { ::operator delete(p); } template inline memory_size_type DB_Row_Impl_Handler::Impl ::total_memory_in_bytes(dimension_type capacity) const { return sizeof(*this) + capacity*sizeof(T) #if !PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS - 1*sizeof(T) #endif + external_memory_in_bytes(); } template inline memory_size_type DB_Row_Impl_Handler::Impl::total_memory_in_bytes() const { // In general, this is a lower bound, as the capacity of *this // may be strictly greater than `size_' return total_memory_in_bytes(size_); } template inline dimension_type DB_Row_Impl_Handler::Impl::max_size() { return std::numeric_limits::max() / sizeof(T); } template inline dimension_type DB_Row_Impl_Handler::Impl::size() const { return size_; } template inline void DB_Row_Impl_Handler::Impl::set_size(const dimension_type new_sz) { size_ = new_sz; } template inline void DB_Row_Impl_Handler::Impl::bump_size() { ++size_; } template inline DB_Row_Impl_Handler::Impl::Impl() : size_(0) { } template inline DB_Row_Impl_Handler::Impl::~Impl() { shrink(0); } template inline DB_Row_Impl_Handler::DB_Row_Impl_Handler() : impl(0) { #if PPL_DB_ROW_EXTRA_DEBUG capacity_ = 0; #endif } template inline DB_Row_Impl_Handler::~DB_Row_Impl_Handler() { delete impl; } template inline T& DB_Row_Impl_Handler::Impl::operator[](const dimension_type k) { PPL_ASSERT(k < size()); return vec_[k]; } template inline const T& DB_Row_Impl_Handler::Impl::operator[](const dimension_type k) const { PPL_ASSERT(k < size()); return vec_[k]; } template inline dimension_type DB_Row::max_size() { return DB_Row_Impl_Handler::Impl::max_size(); } template inline dimension_type DB_Row::size() const { return this->impl->size(); } #if PPL_DB_ROW_EXTRA_DEBUG template inline dimension_type DB_Row::capacity() const { return this->capacity_; } #endif // PPL_DB_ROW_EXTRA_DEBUG template inline DB_Row::DB_Row() : DB_Row_Impl_Handler() { } template inline void DB_Row::allocate( #if PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS const #endif dimension_type capacity) { DB_Row& x = *this; PPL_ASSERT(capacity <= max_size()); #if !PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS if (capacity == 0) ++capacity; #endif PPL_ASSERT(x.impl == 0); x.impl = new (capacity) typename DB_Row_Impl_Handler::Impl(); #if PPL_DB_ROW_EXTRA_DEBUG PPL_ASSERT(x.capacity_ == 0); x.capacity_ = capacity; #endif } template inline void DB_Row::expand_within_capacity(const dimension_type new_size) { DB_Row& x = *this; PPL_ASSERT(x.impl); #if PPL_DB_ROW_EXTRA_DEBUG PPL_ASSERT(new_size <= x.capacity_); #endif x.impl->expand_within_capacity(new_size); } template inline void DB_Row::copy_construct_coefficients(const DB_Row& y) { DB_Row& x = *this; PPL_ASSERT(x.impl && y.impl); #if PPL_DB_ROW_EXTRA_DEBUG PPL_ASSERT(y.size() <= x.capacity_); #endif x.impl->copy_construct_coefficients(*(y.impl)); } template template inline void DB_Row::construct_upward_approximation(const DB_Row& y, const dimension_type capacity) { DB_Row& x = *this; PPL_ASSERT(y.size() <= capacity && capacity <= max_size()); allocate(capacity); PPL_ASSERT(y.impl); x.impl->construct_upward_approximation(*(y.impl)); } template inline void DB_Row::construct(const dimension_type sz, const dimension_type capacity) { PPL_ASSERT(sz <= capacity && capacity <= max_size()); allocate(capacity); expand_within_capacity(sz); } template inline void DB_Row::construct(const dimension_type sz) { construct(sz, sz); } template inline DB_Row::DB_Row(const dimension_type sz, const dimension_type capacity) : DB_Row_Impl_Handler() { construct(sz, capacity); } template inline DB_Row::DB_Row(const dimension_type sz) { construct(sz); } template inline DB_Row::DB_Row(const DB_Row& y) : DB_Row_Impl_Handler() { if (y.impl) { allocate(compute_capacity(y.size(), max_size())); copy_construct_coefficients(y); } } template inline DB_Row::DB_Row(const DB_Row& y, const dimension_type capacity) : DB_Row_Impl_Handler() { PPL_ASSERT(y.impl); PPL_ASSERT(y.size() <= capacity && capacity <= max_size()); allocate(capacity); copy_construct_coefficients(y); } template inline DB_Row::DB_Row(const DB_Row& y, const dimension_type sz, const dimension_type capacity) : DB_Row_Impl_Handler() { PPL_ASSERT(y.impl); PPL_ASSERT(y.size() <= sz && sz <= capacity && capacity <= max_size()); allocate(capacity); copy_construct_coefficients(y); expand_within_capacity(sz); } template inline DB_Row::~DB_Row() { } template inline void DB_Row::shrink(const dimension_type new_size) { DB_Row& x = *this; PPL_ASSERT(x.impl); x.impl->shrink(new_size); } template inline void DB_Row::swap(DB_Row& y) { DB_Row& x = *this; std::swap(x.impl, y.impl); #if PPL_DB_ROW_EXTRA_DEBUG std::swap(x.capacity_, y.capacity_); #endif } template inline void DB_Row::assign(DB_Row& y) { DB_Row& x = *this; x.impl = y.impl; #if PPL_DB_ROW_EXTRA_DEBUG x.capacity_ = y.capacity_; #endif } template inline DB_Row& DB_Row::operator=(const DB_Row& y) { // Copy-construct `tmp' from `y'. DB_Row tmp(y); // Swap the implementation of `*this' with the one of `tmp'. swap(tmp); // Now `tmp' goes out of scope, so the old `*this' will be destroyed. return *this; } template inline T& DB_Row::operator[](const dimension_type k) { DB_Row& x = *this; return (*x.impl)[k]; } template inline const T& DB_Row::operator[](const dimension_type k) const { const DB_Row& x = *this; return (*x.impl)[k]; } template inline typename DB_Row::iterator DB_Row::begin() { DB_Row& x = *this; return iterator(x.impl->vec_); } template inline typename DB_Row::iterator DB_Row::end() { DB_Row& x = *this; return iterator(x.impl->vec_ + x.impl->size_); } template inline typename DB_Row::const_iterator DB_Row::begin() const { const DB_Row& x = *this; return const_iterator(x.impl->vec_); } template inline typename DB_Row::const_iterator DB_Row::end() const { const DB_Row& x = *this; return const_iterator(x.impl->vec_ + x.impl->size_); } template inline memory_size_type DB_Row::external_memory_in_bytes(dimension_type capacity) const { const DB_Row& x = *this; return x.impl->total_memory_in_bytes(capacity); } template inline memory_size_type DB_Row::total_memory_in_bytes(dimension_type capacity) const { return sizeof(*this) + external_memory_in_bytes(capacity); } template inline memory_size_type DB_Row::external_memory_in_bytes() const { const DB_Row& x = *this; #if PPL_DB_ROW_EXTRA_DEBUG return x.impl->total_memory_in_bytes(x.capacity_); #else return x.impl->total_memory_in_bytes(); #endif } template inline memory_size_type DB_Row::total_memory_in_bytes() const { return sizeof(*this) + external_memory_in_bytes(); } /*! \relates DB_Row */ template inline bool operator!=(const DB_Row& x, const DB_Row& y) { return !(x == y); } } // namespace Parma_Polyhedra_Library namespace std { /*! \relates Parma_Polyhedra_Library::DB_Row */ template inline void swap(Parma_Polyhedra_Library::DB_Row& x, Parma_Polyhedra_Library::DB_Row& y) { x.swap(y); } /*! \relates Parma_Polyhedra_Library::DB_Row */ template inline void iter_swap(typename std::vector > ::iterator x, typename std::vector > ::iterator y) { swap(*x, *y); } } // namespace std #endif // !defined(PPL_DB_Row_inlines_hh)