/* * Copyright 2008-2009 Ben Boeckel * * 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 3 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, see . */ /** * \file sigmod/Macros.h * \todo Replace macros with protected methods of Object */ #ifndef SIGMOD_MACROS #define SIGMOD_MACROS #ifdef MAKE_SIGMOD_LIB #include "XmlReader.h" #define LOAD_ARRAY(variable) loadArray(xml.firstChildElement(#variable), &m_##variable) #define SAVE_ARRAY(variable) xml.appendChild(saveArray(#variable, m_##variable)) #define TEST(variable) variable##Check(m_##variable) #define TEST_ARRAY_INDEX(variable, index) variable##Check(index, m_##variable[index]) #define TEST_ARRAY_INDEX_OFF(variable, index, offset) variable##Check(index, m_##variable[index - offset]) #define TEST_LIST(variable) \ foreach (int variable, m_##variable) \ variable##Check(variable) #define TEST_MAP(variable) \ const QList variable##_keys = m_##variable.keys(); \ foreach (int variable, variable##_keys) \ variable##Check(variable, m_##variable[variable]) #define TEST_MATRIX(variable) \ for (int i = 0; i < m_##variable.height(); ++i) \ { \ for (int j = 0; j < m_##variable.width(); ++j) \ variable##Check(i, j, m_##variable(i, j)); \ } #define TS(variable) \ if (variable##Check(variable) && (m_##variable != variable)) \ { \ m_##variable = variable; \ emit(changed()); \ } #define TS_ARRAY(variable, index, offset, value) \ if (variable##Check(index, value) && (m_##variable[index - offset] != value)) \ { \ m_##variable[index - offset] = value; \ emit(changed()); \ } #define TS_MATRIX(variable, row, column, value) \ if (variable##Check(value) && (m_##variable(row, column) != value)) \ { \ m_##variable(row, column) = value; \ emit(changed()); \ } #define TS_LIST_BEGIN(variable) \ if (state && variable##Check(variable) && !m_##variable.contains(variable)) \ { #define TS_LIST_INTERNAL(variable) \ m_##variable.append(variable); \ emit(changed()) #define TS_LIST_INTERNAL_LIMIT(variable, limit, limitError) \ if (m_##variable.size() < limit) \ { \ m_##variable.append(variable); \ emit(changed()); \ } \ else \ ERROR(limitError) #define TS_LIST_END(variable) \ } \ else if (!state && m_##variable.contains(variable)) \ { \ m_##variable.removeOne(variable); \ emit(changed()); \ } #define TS_LIST(variable) \ TS_LIST_BEGIN(variable) \ TS_LIST_INTERNAL(variable); \ TS_LIST_END(variable) #define TS_LIST_LIMIT(variable, limit, limitError) \ TS_LIST_BEGIN(variable) \ TS_LIST_INTERNAL_LIMIT(variable, limit, limitError); \ TS_LIST_END(variable) #define WARNING(msg) emit(warning(msg)) #define ERROR(msg) emit(error(msg)) #define EBOUNDS(variable, min, max) EBOUNDS_MOD(variable, (min), (max), variable) #define EBOUNDS_IDX(variable) emit(error(bounds(#variable, variable))) #define EBOUNDS_MOD(variable, min, max, value) emit(error(bounds(#variable, (min), (max), value))) #define TBOUNDS(variable, min, max) TBOUNDS_MOD(variable, min, max, variable) #define TBOUNDS_MOD(variable, min, max, value) \ { \ const __typeof(min) variable##_min = (min); \ const __typeof(max) variable##_max = (max); \ if ((value < variable##_min) || (variable##_max < value)) \ { \ EBOUNDS_MOD(variable, variable##_min, variable##_max, value); \ return false; \ } \ } #define IBOUNDS(variable, pointer, subclass) \ if (!pointer->subclass##ById(variable)) \ { \ EBOUNDS_IDX(variable); \ return false; \ } #define SETTER(class, type, capital, variable) \ void class::set##capital(const type variable) \ { \ TS(variable); \ } #define SETTER_ARRAY(class, type, capital, variable, valueName, indexType, indexName, offset) \ void class::set##capital(const indexType indexName, const type valueName) \ { \ TS_ARRAY(variable, indexName, offset, valueName); \ } #define SETTER_MATRIX(class, type, capital, variable, valueName) \ void class::set##capital(const int row, const int column, const type valueName) \ { \ TS_MATRIX(variable, row, column, valueName); \ } #define SETTER_LIST(class, capital, variable) \ void class::set##capital(const int variable, const bool state) \ { \ TS_LIST(variable); \ } #define SETTER_LIST_LIMIT(class, capital, variable, limit, limitError) \ void class::set##capital(const int variable, const bool state) \ { \ TS_LIST_LIMIT(variable, limit, limitError); \ } #define SETTER_MAP(class, capital, variable, valueName) \ void class::set##capital(const int variable, const int valueName) \ { \ if (valueName && variable##Check(variable, valueName) && (!m_##variable.contains(variable) || (valueName != m_##variable[variable]))) \ { \ m_##variable[variable] = valueName; \ emit(changed()); \ } \ else if (!valueName && m_##variable.contains(variable)) \ { \ m_##variable.remove(variable); \ emit(changed()); \ } \ } #define GETTER(class, type, variable) \ type class::variable() const \ { \ return m_##variable; \ } #define GETTER_ARRAY(class, type, variable, valueName, indexType, indexName, offset) \ type class::variable(const indexType indexName) const \ { \ if (variable##Check(indexName, m_##variable[indexName - offset])) \ return m_##variable[indexName - offset]; \ return type(); \ } #define GETTER_LIST(class, variable) \ bool class::variable(const int variable) const \ { \ return m_##variable.contains(variable); \ } \ \ QList class::variable() const \ { \ return m_##variable; \ } #define GETTER_MAP(class, variable) \ int class::variable(const int variable) const \ { \ if (m_##variable.contains(variable)) \ return m_##variable[variable]; \ return int(); \ } \ \ QMap class::variable() const \ { \ return m_##variable; \ } #define CHECK_BEGIN(class, type, variable) \ bool class::variable##Check(const type variable) const \ { #define CHECK_BEGIN_ARRAY(class, type, variable, valueName, indexType, indexName) \ bool class::variable##Check(const indexType indexName, const type valueName) const \ { #define CHECK_END() \ return true; \ } #define CHECK(class, type, variable) \ CHECK_BEGIN(class, type, variable) \ Q_UNUSED(variable) \ CHECK_END() #define CHECK_INDEX(class, type, variable, pointer, subclass) \ CHECK_BEGIN(class, type, variable) \ IBOUNDS(variable, pointer, subclass) \ CHECK_END() #define CHECK_BOUNDS(class, type, variable, min, max) \ CHECK_BEGIN(class, type, variable) \ TBOUNDS(variable, (min), (max)) \ CHECK_END() #endif #endif