/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program 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 2 of the License, or (at your option) any later version. This program 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HDR_dbOASIS #define HDR_dbOASIS #include "dbPoint.h" #include "dbVector.h" #include "tlException.h" #include "tlInternational.h" #include "tlString.h" #include "tlAssert.h" #include #include // place this macro to force linking of OASIS plugin #define FORCE_LINK_OASIS void force_link_OASIS_f () { extern int force_link_OASIS; force_link_OASIS = 0; } namespace db { /** * @brief The diagnostics interface for reporting problems in the reader or writer */ class OASISDiagnostics { public: virtual ~OASISDiagnostics (); /** * @brief Issue an error with positional informations */ virtual void error (const std::string &txt) = 0; /** * @brief Issue a warning with positional informations */ virtual void warn (const std::string &txt) = 0; }; class RepetitionBase; class RepetitionIteratorBase; class OASISReader; /** * @brief A repetition iterator */ class DB_PUBLIC RepetitionIterator { public: /** * @brief Create a repetition with the given implementation */ RepetitionIterator (RepetitionIteratorBase *base); /** * @brief Destructor */ ~RepetitionIterator (); /** * @brief Copy constructor */ RepetitionIterator (const RepetitionIterator &d); /** * @brief Assignment */ RepetitionIterator &operator= (const RepetitionIterator &d); /** * @brief Comparison */ bool operator== (const RepetitionIterator &d) const; /** * @brief Inequality */ bool operator!= (const RepetitionIterator &d) const { return !operator== (d); } /** * @brief Tell, if the iterator is at the end */ bool at_end () const; /** * @brief Increment */ RepetitionIterator &operator++ (); /** * @brief Access */ db::Vector operator* () const; private: RepetitionIteratorBase *mp_base; }; /** * @brief A class representing a repetition */ class DB_PUBLIC Repetition { public: /** * @brief Create a repetition with the given implementation */ Repetition (RepetitionBase *base = 0); /** * @brief Destructor */ ~Repetition (); /** * @brief Copy constructor */ Repetition (const Repetition &d); /** * @brief Replace the base pointer */ Repetition &operator= (RepetitionBase *base); /** * @brief Assignment */ Repetition &operator= (const Repetition &d); /** * @brief "Less" predicate */ bool operator< (const Repetition &d) const; /** * @brief Comparison */ bool operator== (const Repetition &d) const; /** * @brief Inequality */ bool operator!= (const Repetition &d) const { return !operator== (d); } /** * @brief Check, if the repetition is an repetition at all * * This method returns true, if the repetition is not singular. * Singular repetitions are created by the default contructor. */ bool is_singular () const { return mp_base == 0; } /** * @brief Check, if the repetition is a regular one * * This method returns true, if the repetition is regular. It * returns true, if the repetition can be represented as a * set of points 0..i*a+j*b (i=0..n-1,j=0..m-1). * This method does not only return a flag but the parameters as * well. */ bool is_regular (db::Vector &a, db::Vector &b, size_t &n, size_t &m) const; /** * @brief Check, if the repepetition is a iterated one * * @return 0 if not, otherwise a pointer to a vector of points */ const std::vector *is_iterated () const; /** * @brief Get the iterator */ RepetitionIterator begin () const; /** * @brief Access to the base object */ void set_base (RepetitionBase *b); /** * @brief Access to the base object */ RepetitionBase *base () { return mp_base; } /** * @brief Access to the base object */ const RepetitionBase *base () const { return mp_base; } private: RepetitionBase *mp_base; }; // Base classes class DB_PUBLIC RepetitionBase { public: RepetitionBase () { // .. nothing yet .. } virtual ~RepetitionBase () { // .. nothing yet .. } virtual RepetitionBase *clone () const = 0; virtual RepetitionIteratorBase *begin () const = 0; virtual unsigned int type () const = 0; virtual bool equals (const RepetitionBase *) const = 0; virtual bool less (const RepetitionBase *) const = 0; virtual bool is_regular (db::Vector &a, db::Vector &b, size_t &n, size_t &m) const = 0; virtual const std::vector *is_iterated () const = 0; virtual unsigned int type () = 0; }; class RepetitionIteratorBase { public: RepetitionIteratorBase () { // .. nothing yet .. } virtual ~RepetitionIteratorBase () { // .. nothing yet .. } virtual RepetitionIteratorBase *clone () const = 0; virtual void inc () = 0; virtual db::Vector get () const = 0; virtual unsigned int type () const = 0; virtual bool equals (const RepetitionIteratorBase *) const = 0; virtual bool at_end () const = 0; }; // Regular repetitions class RegularRepetition : public RepetitionBase { public: RegularRepetition (const db::Vector &a, const db::Vector &b, size_t n, size_t m); virtual RepetitionBase *clone () const; virtual RepetitionIteratorBase *begin () const; virtual unsigned int type () const; virtual bool equals (const RepetitionBase *b) const; virtual bool less (const RepetitionBase *b) const; virtual bool is_regular (db::Vector &a, db::Vector &b, size_t &n, size_t &m) const; virtual const std::vector *is_iterated () const; virtual unsigned int type () { return 1; } private: friend class RegularRepetitionIterator; db::Vector m_a, m_b; size_t m_n, m_m; }; class RegularRepetitionIterator : public RepetitionIteratorBase { public: RegularRepetitionIterator (const RegularRepetition *rep, size_t i, size_t j); virtual RepetitionIteratorBase *clone () const; virtual void inc (); virtual db::Vector get () const; virtual unsigned int type () const; virtual bool equals (const RepetitionIteratorBase *) const; virtual bool at_end () const; private: const RegularRepetition *mp_rep; size_t m_i, m_j; }; // Irregular repetitions class IrregularRepetition : public RepetitionBase { public: IrregularRepetition (); virtual RepetitionBase *clone () const; virtual RepetitionIteratorBase *begin () const; virtual unsigned int type () const; virtual bool equals (const RepetitionBase *b) const; virtual bool less (const RepetitionBase *b) const; virtual bool is_regular (db::Vector &a, db::Vector &b, size_t &n, size_t &m) const; virtual const std::vector *is_iterated () const; virtual unsigned int type () { return 2; } void reserve (size_t n) { m_points.reserve (n); } void push_back (const db::Vector &v) { m_points.push_back (v); } std::vector &points () { return m_points; } private: friend class IrregularRepetitionIterator; std::vector m_points; }; class IrregularRepetitionIterator : public RepetitionIteratorBase { public: IrregularRepetitionIterator (const IrregularRepetition *rep, size_t i); virtual RepetitionIteratorBase *clone () const; virtual void inc (); virtual db::Vector get () const; virtual unsigned int type () const; virtual bool equals (const RepetitionIteratorBase *) const; virtual bool at_end () const; private: const IrregularRepetition *mp_rep; size_t m_i; }; /** * @brief A template class representing a modal variable */ template class modal_variable { public: /** * @brief Set up the modal variable * * The reader is required since errors are reported to the reader. * The name is reported in the error message. * This constructor creates an uninitialized variable. */ modal_variable (OASISDiagnostics *reader = 0, const char *name = "") : mp_diag (reader), m_name (name), m_t (), m_initialized (false) { // .. nothing yet .. } /** * @brief Get the value of the modal variable * * An error will be reported if the value is not initialized. */ const T &get () const; /** * @brief Get the value of the modal variable * * This method does not report an error if the value is not initialized. * After modifying the object, set_initialized is supposed to be called. */ T &get_non_const () { return m_t; } /** * @brief Equality */ bool operator== (const T &t) const { return (m_initialized && m_t == t); } /** * @brief Inequality */ bool operator!= (const T &t) const { return !operator== (t); } /** * @brief Assignment operator */ modal_variable &operator= (const modal_variable &d) { m_t = d.m_t; m_initialized = d.m_initialized; return *this; } /** * @brief Assign a value to the modal variable * * This sets the variable into the initialized state. */ template modal_variable &operator= (const X &x) { m_t = x; m_initialized = true; return *this; } /** * @brief Swap with a target value (mainly intended for T==vector) * * This sets the variable into the initialized state. */ template modal_variable &swap (X &x) { m_t.swap (x); m_initialized = true; return *this; } /** * @brief Reset the initialized state of the variable */ void reset () { m_initialized = false; } /** * @brief Set the initialized state of the variable * * This method is supposed to be used after a modification has been performed * with the non-const accessor. */ void set_initialized () { m_initialized = true; } /** * @brief Test, if the variable is set */ bool is_set () const { return m_initialized; } private: OASISDiagnostics *mp_diag; std::string m_name; T m_t; bool m_initialized; }; template inline const T & modal_variable::get () const { if (! m_initialized) { if (mp_diag) { mp_diag->warn (tl::to_string (QObject::tr ("Modal variable accessed before being defined: ")) + m_name); } else { tl_assert (false); } } return m_t; } } #endif