mirror of https://github.com/KLayout/klayout.git
521 lines
11 KiB
C++
521 lines
11 KiB
C++
|
|
/*
|
|
|
|
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 <string>
|
|
#include <vector>
|
|
|
|
// 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<db::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<db::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<db::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<db::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<db::Vector> &points ()
|
|
{
|
|
return m_points;
|
|
}
|
|
|
|
private:
|
|
friend class IrregularRepetitionIterator;
|
|
|
|
std::vector <db::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 T>
|
|
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<T> &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 <class X>
|
|
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<something>)
|
|
*
|
|
* This sets the variable into the initialized state.
|
|
*/
|
|
template <class X>
|
|
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 <class T>
|
|
inline const T &
|
|
modal_variable<T>::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
|
|
|