/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include namespace MiniZinc { class ASTIntVecO; /** * \brief Handler for ASTIntVecO objects */ class ASTIntVec { protected: /// Vector ASTIntVecO* _v; public: /// Default constructor ASTIntVec() : _v(nullptr) {} /// Constructor ASTIntVec(ASTIntVecO* v) : _v(v) {} /// Constructor ASTIntVec(const std::vector& v); /// Copy constructor ASTIntVec(const ASTIntVec& v); /// Assignment operator ASTIntVec& operator=(const ASTIntVec& v); /// Size of vector unsigned int size() const; /// Element access int& operator[](unsigned int i); /// Element access int operator[](unsigned int i) const; /// Iterator begin int* begin(); /// Iterator end int* end(); /// Mark as alive for garbage collection void mark() const; }; template class ASTExprVecO; /** * \brief Handler for ASTExprVecO objects */ template class ASTExprVec { protected: /// Vector ASTExprVecO* _v; public: /// Default constructor ASTExprVec() : _v(nullptr) {} /// Constructor ASTExprVec(ASTExprVecO* v) : _v(v) {} /// Constructor ASTExprVec(const std::vector& v); /// Copy constructor ASTExprVec(const ASTExprVec& v); /// Assignment operator // NOLINTNEXTLINE(bugprone-unhandled-self-assignment) ASTExprVec& operator=(const ASTExprVec& v); /// Size of vector unsigned int size() const; /// Element access T*& operator[](unsigned int i); /// Element access T* operator[](unsigned int i) const; /// Iterator begin T** begin(); /// Iterator end T** end(); /// Return vector object ASTExprVecO* vec() const; /// Mark as alive for garbage collection void mark() const; }; /// Garbage collected integer vector class ASTIntVecO : public ASTChunk { protected: /// Constructor ASTIntVecO(const std::vector& v); public: /// Allocate and initialise from \a v static ASTIntVecO* a(const std::vector& v); /// Return size unsigned int size() const { return static_cast(_size / sizeof(int)); } /// Return element at position \a i int& operator[](unsigned int i) { assert(i < size()); return reinterpret_cast(_data)[i]; } /// Return element at position \a i int operator[](unsigned int i) const { assert(i < size()); return reinterpret_cast(_data)[i]; } /// Iterator begin int* begin() { return reinterpret_cast(_data); } /// Iterator end int* end() { return begin() + size(); } /// Mark as alive for garbage collection void mark() const { _gcMark = 1; } }; /// Garbage collected vector of expressions template class ASTExprVecO : public ASTVec { protected: /// Constructor ASTExprVecO(const std::vector& v); public: /// Allocate and initialise from \a v static ASTExprVecO* a(const std::vector& v); unsigned int size() const { return static_cast(_size); } bool empty() const { return size() == 0; } T& operator[](unsigned int i) { assert(i < static_cast(size())); return reinterpret_cast(_data[i]); } T operator[](unsigned int i) const { assert(i < static_cast(size())); return reinterpret_cast(_data[i]); } /// Iterator begin T* begin() { return reinterpret_cast(_data); } /// Iterator end T* end() { return begin() + size(); } /// Mark as alive for garbage collection void mark() const { _gcMark = 1; } /// Check if flag is set bool flag() const { return _flag1; } /// Set flag void flag(bool f) { _flag1 = f; } }; template ASTExprVecO::ASTExprVecO(const std::vector& v) : ASTVec(v.size()) { _flag1 = false; for (auto i = static_cast(v.size()); (i--) != 0U;) { (*this)[i] = v[i]; } } template ASTExprVecO* ASTExprVecO::a(const std::vector& v) { auto* ao = static_cast*>(alloc(v.size())); new (ao) ASTExprVecO(v); return ao; } inline ASTIntVec::ASTIntVec(const std::vector& v) : _v(ASTIntVecO::a(v)) {} inline ASTIntVec::ASTIntVec(const ASTIntVec& v) : _v(v._v) {} // NOLINTNEXTLINE(bugprone-unhandled-self-assignment) inline ASTIntVec& ASTIntVec::operator=(const ASTIntVec& v) { _v = v._v; return *this; } inline unsigned int ASTIntVec::size() const { return _v != nullptr ? _v->size() : 0; } inline int& ASTIntVec::operator[](unsigned int i) { return (*_v)[i]; } inline int ASTIntVec::operator[](unsigned int i) const { return (*_v)[i]; } inline int* ASTIntVec::begin() { return _v != nullptr ? _v->begin() : nullptr; } inline int* ASTIntVec::end() { return _v != nullptr ? _v->end() : nullptr; } inline void ASTIntVec::mark() const { if (_v != nullptr) { _v->mark(); } } template ASTExprVec::ASTExprVec(const std::vector& v) : _v(ASTExprVecO::a(v)) {} template inline ASTExprVec::ASTExprVec(const ASTExprVec& v) : _v(v._v) {} template // NOLINTNEXTLINE(bugprone-unhandled-self-assignment) inline ASTExprVec& ASTExprVec::operator=(const ASTExprVec& v) { _v = v._v; return *this; } template inline unsigned int ASTExprVec::size() const { return _v ? _v->size() : 0; } template inline T*& ASTExprVec::operator[](unsigned int i) { return (*_v)[i]; } template inline T* ASTExprVec::operator[](unsigned int i) const { return (*_v)[i]; } template inline T** ASTExprVec::begin() { return _v ? _v->begin() : nullptr; } template inline T** ASTExprVec::end() { return _v ? _v->end() : nullptr; } template inline ASTExprVecO* ASTExprVec::vec() const { return _v; } template inline void ASTExprVec::mark() const { if (_v) { _v->mark(); } } } // namespace MiniZinc