diff --git a/api/c/bingo-nosql/src/bingo_container_set.cpp b/api/c/bingo-nosql/src/bingo_container_set.cpp index ead2757916..916682f627 100644 --- a/api/c/bingo-nosql/src/bingo_container_set.cpp +++ b/api/c/bingo-nosql/src/bingo_container_set.cpp @@ -195,7 +195,7 @@ int ContainerSet::_findSimilarInc(const byte* query, SimCoef& sim_coef, double m if (coef < min_coef) continue; - sim_indices.push(SimResult(indices[i], (float)coef)); + sim_indices.push_back(SimResult(indices[i], (float)coef)); } return sim_indices.size(); diff --git a/api/c/bingo-nosql/src/bingo_matcher.cpp b/api/c/bingo-nosql/src/bingo_matcher.cpp index fbc41654f6..b937737eea 100644 --- a/api/c/bingo-nosql/src/bingo_matcher.cpp +++ b/api/c/bingo-nosql/src/bingo_matcher.cpp @@ -1053,9 +1053,7 @@ void TopNSimMatcher::_findTopN() while (BaseSimilarityMatcher::next()) { cnt++; - res = &_current_results.push(); - res->id = _current_id; - res->sim_value = _current_sim_value; + res = &_current_results.emplace_back(_current_id, _current_sim_value); cur_cell = currentCell(); if ((cnt > hits_limit * 2) && ((max_cell - cur_cell) > cells_count / 2)) { @@ -1109,9 +1107,7 @@ void TopNSimMatcher::_findTopN() while (BaseSimilarityMatcher::next()) { cnt++; - res = &_current_results.push(); - res->id = _current_id; - res->sim_value = _current_sim_value; + res = &_current_results.emplace_back(_current_id, _current_sim_value); if (cnt > hits_limit * 2) { @@ -1186,9 +1182,7 @@ void TopNSimMatcher::_findTopN() while (BaseSimilarityMatcher::next()) { cnt++; - res = &_current_results.push(); - res->id = _current_id; - res->sim_value = _current_sim_value; + res = &_current_results.emplace_back(_current_id, _current_sim_value); cur_cell = currentCell(); if ((cnt > hits_limit * 2) && (max_cell - cur_cell) > cells_count / 2) { @@ -1246,7 +1240,7 @@ void TopNSimMatcher::_findTopN() for (i = 0; i < _current_results.size(); i++) { _result_ids.push(_current_results[i].id); - _result_sims.push(_current_results[i].sim_value); + _result_sims.push_back(_current_results[i].sim_value); if (i == (hits_limit - 1)) break; @@ -1268,7 +1262,7 @@ void TopNSimMatcher::_initModelDistribution(Array& model_thrs, Array { for (int i = 0; i < 9; i++) { - model_thrs.push(_2FLOAT(1.0 - 0.1 * (i + 1))); + model_thrs.push_back(_2FLOAT(1.0 - 0.1 * (i + 1))); model_nhits_per_block.push(5 * 2 ^ (i)); } } diff --git a/api/c/bingo-nosql/src/bingo_multibit_tree.cpp b/api/c/bingo-nosql/src/bingo_multibit_tree.cpp index 31df654c15..1a5bfc4968 100644 --- a/api/c/bingo-nosql/src/bingo_multibit_tree.cpp +++ b/api/c/bingo-nosql/src/bingo_multibit_tree.cpp @@ -137,7 +137,7 @@ void MultibitTree::_build() QS_DEF(Array, is_mb); is_mb.clear_resize(_fp_size * 8); - is_mb.zerofill(); + is_mb.fill(false); _tree_ptr = _buildNode(indices, is_mb, 0); } @@ -160,7 +160,7 @@ void MultibitTree::_findLinear(_MultibitNode* node, const byte* query, int query if (coef < min_coef) continue; - sim_indices.push(SimResult(indices[fp_indices[i]], (float)coef)); + sim_indices.push_back(SimResult(indices[fp_indices[i]], (float)coef)); } } @@ -207,9 +207,9 @@ void MultibitTree::_findSimilarInNode(MMFPtr<_MultibitNode> node_ptr, const byte _findSimilarInNode(node->right, query, query_bit_number, sim_coef, min_coef, right_indices, right_m01, right_m10); for (int i = 0; i < left_indices.size(); i++) - sim_indices.push(left_indices[i]); + sim_indices.push_back(left_indices[i]); for (int i = 0; i < right_indices.size(); i++) - sim_indices.push(right_indices[i]); + sim_indices.push_back(right_indices[i]); } MultibitTree::MultibitTree(int fp_size) : _fp_size(fp_size) diff --git a/api/c/bingo-nosql/src/bingo_sim_coef.h b/api/c/bingo-nosql/src/bingo_sim_coef.h index 8ac78ec353..1dad7cc783 100644 --- a/api/c/bingo-nosql/src/bingo_sim_coef.h +++ b/api/c/bingo-nosql/src/bingo_sim_coef.h @@ -10,6 +10,10 @@ namespace bingo int id; float sim_value; + SimResult() : id(0), sim_value(0) + { + } + SimResult(int new_id, float new_sim_value) : id(new_id), sim_value(new_sim_value) { } diff --git a/api/c/bingo-nosql/src/bingo_sim_storage.cpp b/api/c/bingo-nosql/src/bingo_sim_storage.cpp index 4843f3cb2f..3d1709a5e4 100644 --- a/api/c/bingo-nosql/src/bingo_sim_storage.cpp +++ b/api/c/bingo-nosql/src/bingo_sim_storage.cpp @@ -118,7 +118,7 @@ int SimStorage::getIncSimilar(const byte* query, SimCoef& sim_coef, double min_c continue; size_t id = _inc_id_buffer[i]; - sim_fp_indices.push(SimResult(id, _2FLOAT(coef))); + sim_fp_indices.push_back(SimResult(id, _2FLOAT(coef))); } return sim_fp_indices.size(); diff --git a/api/c/bingo-nosql/src/mmf/mmf_mapping.cpp b/api/c/bingo-nosql/src/mmf/mmf_mapping.cpp index 518c57dab2..3ac515c397 100644 --- a/api/c/bingo-nosql/src/mmf/mmf_mapping.cpp +++ b/api/c/bingo-nosql/src/mmf/mmf_mapping.cpp @@ -36,7 +36,7 @@ void MMFMapping::getAll(size_t id1, Array& id2_array) for (i = 0; i < it->count; i++) { if (it->buf[i].first == id1) - id2_array.push(it->buf[i].second); + id2_array.push_back(it->buf[i].second); } } } diff --git a/api/c/indigo-inchi/CMakeLists.txt b/api/c/indigo-inchi/CMakeLists.txt index 962aa7c1e4..230f38b375 100644 --- a/api/c/indigo-inchi/CMakeLists.txt +++ b/api/c/indigo-inchi/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(${PROJECT_NAME}-object if (NOT EMSCRIPTEN) add_library(${PROJECT_NAME} SHARED $) - target_link_libraries(${PROJECT_NAME} PRIVATE indigo indigo-core) + target_link_libraries(${PROJECT_NAME} PRIVATE indigo) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/) diff --git a/api/c/indigo/src/indigo_abbreviations_expand.cpp b/api/c/indigo/src/indigo_abbreviations_expand.cpp index 0c6a18ad16..a5ead2032b 100644 --- a/api/c/indigo/src/indigo_abbreviations_expand.cpp +++ b/api/c/indigo/src/indigo_abbreviations_expand.cpp @@ -687,19 +687,19 @@ namespace indigo if (on_right && !on_left) { - options.push(Options(RIGHT, RIGHT)); - options.push(Options(LEFT, LEFT)); + options.push_back(Options(RIGHT, RIGHT)); + options.push_back(Options(LEFT, LEFT)); } else { if (on_right) - options.push(Options(RIGHT, RIGHT)); + options.push_back(Options(RIGHT, RIGHT)); if (on_left) { - options.push(Options(LEFT, LEFT)); - options.push(Options(LEFT, RIGHT)); - options.push(Options(RIGHT, RIGHT)); - options.push(Options(LEFT, LEFT, 2)); + options.push_back(Options(LEFT, LEFT)); + options.push_back(Options(LEFT, RIGHT)); + options.push_back(Options(RIGHT, RIGHT)); + options.push_back(Options(LEFT, LEFT, 2)); } } @@ -709,7 +709,7 @@ namespace indigo { Options opt = options[i]; opt.ignore_case = true; - options.push(opt); + options.push_back(opt); } bool found = false; diff --git a/api/c/indigo/src/indigo_deconvolution.cpp b/api/c/indigo/src/indigo_deconvolution.cpp index 62f66df042..26059b1efa 100644 --- a/api/c/indigo/src/indigo_deconvolution.cpp +++ b/api/c/indigo/src/indigo_deconvolution.cpp @@ -1035,6 +1035,11 @@ IndigoDecompositionMatch::IndigoDecompositionMatch() : IndigoObject(DECOMPOSITIO { } +IndigoDecompositionMatch::IndigoDecompositionMatch(const IndigoDecompositionMatch& other) : IndigoObject(DECOMPOSITION_MATCH), deco(0), _completeScaffold(false) +{ + copy(const_cast(other)); +} + bool IndigoDeconvolution::_matchAtoms(Graph& g1, Graph& g2, const int*, int sub_idx, int super_idx, void* userdata) { if (userdata == 0) diff --git a/api/c/indigo/src/indigo_deconvolution.h b/api/c/indigo/src/indigo_deconvolution.h index cc4c1abf5e..de1a8f0348 100644 --- a/api/c/indigo/src/indigo_deconvolution.h +++ b/api/c/indigo/src/indigo_deconvolution.h @@ -171,6 +171,8 @@ class DLLEXPORT IndigoDecompositionMatch : public IndigoObject { public: IndigoDecompositionMatch(); + IndigoDecompositionMatch(const IndigoDecompositionMatch& other); + Array visitedAtoms; Array scaffoldBonds; Array scaffoldAtoms; @@ -196,10 +198,6 @@ class DLLEXPORT IndigoDecompositionMatch : public IndigoObject Molecule mol_scaffold; IndigoDeconvolution* deco; - -private: - IndigoDecompositionMatch(const IndigoDecompositionMatch&); // no implicit copy - bool _completeScaffold; }; diff --git a/api/c/indigo/src/indigo_molecule.cpp b/api/c/indigo/src/indigo_molecule.cpp index 493283a8d5..f83cc9c9cd 100644 --- a/api/c/indigo/src/indigo_molecule.cpp +++ b/api/c/indigo/src/indigo_molecule.cpp @@ -2051,8 +2051,8 @@ CEXPORT float indigoAlignAtoms(int molecule, int natoms, int* atom_ids, float* d for (i = 0; i < natoms; i++) { - points.push(mol.getAtomXyz(atom_ids[i])); - goals.push(Vec3f(desired_xyz[i * 3], desired_xyz[i * 3 + 1], desired_xyz[i * 3 + 2])); + points.push_back(mol.getAtomXyz(atom_ids[i])); + goals.push_back(Vec3f(desired_xyz[i * 3], desired_xyz[i * 3 + 1], desired_xyz[i * 3 + 2])); } if (points.size() < 1) @@ -3307,13 +3307,13 @@ CEXPORT int indigoSetSGroupBrackets(int sgroup, int brk_style, float x1, float y psg->brk_style = brk_style; psg->brackets.clear(); - Vec2f* brackets = psg->brackets.push(); + std::array brackets; brackets[0].set(x1, y1); brackets[1].set(x2, y2); - brackets = psg->brackets.push(); + psg->brackets.push_back(brackets); brackets[0].set(x3, y3); brackets[1].set(x4, y4); - + psg->brackets.push_back(brackets); return 1; } INDIGO_END(-1); diff --git a/api/c/indigo/src/indigo_object.cpp b/api/c/indigo/src/indigo_object.cpp index 82cf0e17a1..6d7705c899 100644 --- a/api/c/indigo/src/indigo_object.cpp +++ b/api/c/indigo/src/indigo_object.cpp @@ -25,7 +25,7 @@ #include "reaction/reaction.h" using IndigoObjectTypesMap = std::map; -class IndigoObjectTypes : public IndigoObjectTypesMap, public NonCopyable +class IndigoObjectTypes : public IndigoObjectTypesMap { public: IndigoObjectTypes(); diff --git a/bingo/oracle/src/oracle/bingo_fingerprints.cpp b/bingo/oracle/src/oracle/bingo_fingerprints.cpp index 6f9ecc9612..3d0f484c9e 100644 --- a/bingo/oracle/src/oracle/bingo_fingerprints.cpp +++ b/bingo/oracle/src/oracle/bingo_fingerprints.cpp @@ -110,7 +110,7 @@ void BingoFingerprints::addFingerprint(OracleEnv& env, const byte* fp) } ptr += 8 * _chunk_qwords; } - _pending_block.mapping.push(_pending_block.mapping.size()); + _pending_block.mapping.push_back(_pending_block.mapping.size()); _pending_block.used++; } diff --git a/bingo/oracle/src/oracle/bingo_storage.cpp b/bingo/oracle/src/oracle/bingo_storage.cpp index 7e41e2b8ac..fdbf654b23 100644 --- a/bingo/oracle/src/oracle/bingo_storage.cpp +++ b/bingo/oracle/src/oracle/bingo_storage.cpp @@ -115,7 +115,7 @@ void BingoStorage::validateForInsert(OracleEnv& env) continue; } - _Block& block = _blocks.push(); + _Block& block = _blocks.emplace_back(); block.size = length; } while (statement.fetch()); @@ -244,7 +244,7 @@ void BingoStorage::validate(OracleEnv& env) _index.copy((_Addr*)_shmem_array[0]->ptr(), length / sizeof(_Addr)); } - _Block& block = _blocks.push(); + _Block& block = _blocks.emplace_back(); block.size = length; } while (statement.fetch()); @@ -305,7 +305,7 @@ void BingoStorage::_insertLOB(OracleEnv& env, int no) if (no > 0) { - _Block& block = _blocks.push(); + _Block& block = _blocks.emplace_back(); block.size = 0; } diff --git a/bingo/oracle/src/oracle/mango_shadow_table.cpp b/bingo/oracle/src/oracle/mango_shadow_table.cpp index 49fdadbd6e..2facfb9f11 100644 --- a/bingo/oracle/src/oracle/mango_shadow_table.cpp +++ b/bingo/oracle/src/oracle/mango_shadow_table.cpp @@ -86,13 +86,13 @@ void MangoShadowTable::addMolecule(OracleEnv& env, const char* rowid, int blockn _main_table_statement->append(")"); } - _pending_rid.push(); + _pending_rid.emplace_back(); strncpy(_pending_rid.top(), rowid, 19); _pending_blockno.push(blockno); _pending_offset.push(offset); - _pending_gross.push(); + _pending_gross.emplace_back(); strncpy(_pending_gross.top(), gross, 512); - _pending_mass.push(molecular_mass); + _pending_mass.push_back(molecular_mass); _pending_cmf.push(env); _pending_cmf.top().assignBytes(data_cmf, len_cmf); @@ -130,9 +130,9 @@ void MangoShadowTable::addMolecule(OracleEnv& env, const char* rowid, int blockn for (int i = 0; i < hash.size(); i++) { - _pending_comp_hash.push(); + _pending_comp_hash.emplace_back(); snprintf(_pending_comp_hash.top(), 9, "%08X", hash[i].hash); - _pending_comp_rid.push(); + _pending_comp_rid.emplace_back(); strncpy(_pending_comp_rid.top(), rowid, 19); _pending_comp_count.push(hash[i].count); _components_table_statement_count++; @@ -205,10 +205,10 @@ void MangoShadowTable::_flushMain(OracleEnv& env) if (_pending_xyz[i].get() != 0) { memcpy(xyz.ptr() + i * (maxallocsize_xyz + 4), _pending_xyz[i].get(), _pending_xyz[i].getAllocSize() + 4); - xyz_ind.push(0); // OCI_IND_NOTNULL + xyz_ind.push_back(0); // OCI_IND_NOTNULL } else - xyz_ind.push(-1); // OCI_IND_NULL + xyz_ind.push_back(-1); // OCI_IND_NULL } _main_table_statement->bindRawPtrByName(":cmf", (OCIRaw*)cmf.ptr(), maxallocsize_cmf, 0); diff --git a/bingo/postgres/src/pg_am/pg_bingo_import.cpp b/bingo/postgres/src/pg_am/pg_bingo_import.cpp index a97d30bc22..3381208ce3 100644 --- a/bingo/postgres/src/pg_am/pg_bingo_import.cpp +++ b/bingo/postgres/src/pg_am/pg_bingo_import.cpp @@ -353,7 +353,7 @@ class BingoImportHandler : public BingoPgCommon::BingoSessionHandler for (int col_idx = 0; col_idx < _importColumns.size(); ++col_idx) { q_nulls.push(0); - q_oids.push(_importColumns[col_idx].type); + q_oids.push_back(_importColumns[col_idx].type); if (col_idx != 0) query_string.printf(", "); @@ -397,7 +397,7 @@ class BingoImportHandler : public BingoPgCommon::BingoSessionHandler q_values.clear(); for (int q_idx = 0; q_idx < _importData.size(); ++q_idx) { - q_values.push(_importData[q_idx]->getDatum()); + q_values.push_back(_importData[q_idx]->getDatum()); if (q_values[q_idx] == 0) { q_nulls[q_idx] = 'n'; diff --git a/core/indigo-core/common/base_cpp/array.h b/core/indigo-core/common/base_cpp/array.h index bb83161e89..df213ee079 100644 --- a/core/indigo-core/common/base_cpp/array.h +++ b/core/indigo-core/common/base_cpp/array.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "base_c/defs.h" #include "base_cpp/exception.h" @@ -44,6 +45,11 @@ namespace indigo { } + Array(const Array& other) + { + copy(other); + } + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) { other._array = nullptr; @@ -169,49 +175,21 @@ namespace indigo void copy(const Array& other) { - copy(other._array, other._length); + _length = 0; + concat(other); } void copy(const T* other, int count) { - if (count > 0) - { - clear_resize(count); - memcpy(_array, other, count * sizeof(T)); - } - else - { - _length = 0; - } + _length = 0; + for (int i = 0; i < count; ++i) + push_back(other[i]); } void concat(const Array& other) { - concat(other._array, other.size()); - } - - void concat(const T* other, int count) - { - if (count > 0) - { - int length = _length; - resize(length + count); - - memcpy(_array + length, other, count * sizeof(T)); - } - } - - int memcmp(const Array& other) const - { - if (_length < other._length) - return -1; - if (_length > other._length) - return -1; - - if (_length == 0) - return 0; - - return ::memcmp(_array, other._array, _length * sizeof(T)); + for (int i = 0; i < other.size(); ++i) + push_back(other[i]); } void remove(int idx, int span = 1) @@ -223,46 +201,6 @@ namespace indigo _length -= span; } - void remove_replace(int idx) - { - if (idx < 0 || idx >= _length) - throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); - - if (idx < _length - 1) - _array[idx] = _array[_length - 1]; - - _length--; - } - - int find(const T& value) const - { - return find(0, _length, value); - } - - int find(int from, int to, const T& value) const - { - for (int i = from; i < to; i++) - if (_array[i] == value) - return i; - - return -1; - } - - int count(const T& value) const - { - return count(0, _length, value); - } - - int count(int from, int to, const T& value) const - { - int cnt = 0; - for (int i = from; i < to; i++) - if (_array[i] == value) - cnt++; - - return cnt; - } - void swap(int idx1, int idx2) { if (idx1 < 0 || idx1 >= _length) @@ -277,24 +215,25 @@ namespace indigo std::swap(_array[idx1], _array[idx2]); } - void push(T elem) - { - resize(_length + 1); - _array[_length - 1] = elem; - } - - T& push() + T& push_back(const T& elem) { resize(_length + 1); + new ((void*)&_array[_length - 1]) T(elem); return _array[_length - 1]; } - T& pop() + template + T& emplace_back(Args&&... args); + + template + T& replace(int idx, Args&&... args); + + void pop_back() { if (_length <= 0) throw Error("stack underflow"); - - return _array[--_length]; + --_length; + memset(_array + _length, 0, sizeof(T)); } T& top() @@ -345,7 +284,7 @@ namespace indigo void expandFill(int newsize, const T& value) { while (_length < newsize) - push(value); + push_back(value); } void clear_resize(int newsize) @@ -355,7 +294,7 @@ namespace indigo _length = 0; reserve((newsize + 1) * 2); } - _length = newsize; + resize(newsize); } void swap(Array& other) @@ -499,85 +438,2956 @@ namespace indigo this->qsort(0, _length - 1, cmp, context); } - // Array-specific - void appendString(const char* str, bool keep_zero) + protected: + T* _array; + + int _reserved; + int _length; + + template + class _CmpFunctorCaller { - int len = (int)strlen(str); - int initial_size = _length; + public: + _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + { + } - if (initial_size > 0 && _array[initial_size - 1] == 0) - initial_size--; + int operator()(T1 arg1, T2 arg2) const + { + return _cmp(arg1, arg2, _context); + } - resize(initial_size + len); - memcpy(_array + initial_size, str, len); + private: + void* _context; + int (*_cmp)(T1, T2, void*); + }; + }; - if (keep_zero) - push(0); + template + template + T& Array::emplace_back(Args&&... args) + { + resize(_length + 1); + new ((void*)&_array[_length - 1]) T(args...); + return _array[_length - 1]; + } + + template + template + T& Array::replace(int idx, Args&&... args) + { + new (&_array[idx]) T(args...); + return _array[_length - 1]; + } + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { } - void readString(const char* str, bool keep_zero) + Array(const Array& other) { - clear(); - appendString(str, keep_zero); + copy(other); } - void upper(const char* source) + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) { - clear(); - while (*source != 0) - push(::toupper(*source++)); - push(0); + other._array = nullptr; + other._length = 0; + other._reserved = 0; } - void lower(const char* source) + ~Array() { - clear(); - while (*source != 0) - push(::tolower(*source++)); - push(0); + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } } - void toupper() + void clear() { - for (int i = 0; i < _length; i++) - _array[i] = ::toupper(_array[i]); + _length = 0; } - void tolower() + void reserve(int to_reserve) { - for (int i = 0; i < _length; i++) - _array[i] = ::tolower(_array[i]); + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + bool* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(bool) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } } - protected: - T* _array; + void fill(const bool& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } - int _reserved; - int _length; + const bool* ptr() const + { + return _array; + } - private: - Array(const Array&); // no implicit copy - Array& operator=(const Array& right); // no copy constructor + bool* ptr() + { + return _array; + } - template - class _CmpFunctorCaller + const bool& operator[](int index) const { - public: - _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + bool& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const bool& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + bool& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(bool); + } + + void copy(const Array& other) + { + copy(other._array, other._length); + } + + void copy(const bool* other, int count) + { + if (count > 0) { + clear_resize(count); + memcpy(_array, other, count * sizeof(bool)); } - - int operator()(T1 arg1, T2 arg2) const + else { - return _cmp(arg1, arg2, _context); + _length = 0; } + } - private: - void* _context; - int (*_cmp)(T1, T2, void*); + void concat(const Array& other) + { + concat(other._array, other.size()); + } + + void concat(const bool* other, int count) + { + if (count > 0) + { + int length = _length; + resize(length + count); + + memcpy(_array + length, other, count * sizeof(bool)); + } + } + + int memcmp(const Array& other) const + { + if (_length < other._length) + return -1; + if (_length > other._length) + return -1; + + if (_length == 0) + return 0; + + return ::memcmp(_array, other._array, _length * sizeof(bool)); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(bool) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int find(const bool& value) const + { + return find(0, _length, value); + } + + int find(int from, int to, const bool& value) const + { + for (int i = from; i < to; i++) + if (_array[i] == value) + return i; + + return -1; + } + + int count(const bool& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const bool& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + void push(bool elem) + { + resize(_length + 1); + _array[_length - 1] = elem; + } + + bool& push() + { + resize(_length + 1); + return _array[_length - 1]; + } + + bool& pop() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[--_length]; + } + + bool& top() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + const bool& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + bool& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const bool& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const bool& value) + { + while (_length < newsize) + push(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + bool* begin() + { + return _array; + } + + bool* end() + { + return _array + _length; + } + + protected: + bool* _array; + + int _reserved; + int _length; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(const Array& other) + { + copy(other); + } + + Array& operator=(const Array& other) + { + copy(other); + return *this; + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + char* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(char) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(char)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(char)); + } + + void fill(const char& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const char* ptr() const + { + return _array; + } + + char* ptr() + { + return _array; + } + + const char& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + char& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const char& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + char& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(char); + } + + void copy(const Array& other) + { + copy(other._array, other._length); + } + + void copy(const char* other, int count) + { + if (count > 0) + { + clear_resize(count); + memcpy(_array, other, count * sizeof(char)); + } + else + { + _length = 0; + } + } + + void concat(const Array& other) + { + concat(other._array, other.size()); + } + + void concat(const char* other, int count) + { + if (count > 0) + { + int length = _length; + resize(length + count); + + memcpy(_array + length, other, count * sizeof(char)); + } + } + + int memcmp(const Array& other) const + { + if (_length < other._length) + return -1; + if (_length > other._length) + return -1; + + if (_length == 0) + return 0; + + return ::memcmp(_array, other._array, _length * sizeof(char)); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(char) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int find(const char& value) const + { + return find(0, _length, value); + } + + int find(int from, int to, const char& value) const + { + for (int i = from; i < to; i++) + if (_array[i] == value) + return i; + + return -1; + } + + int count(const char& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const char& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + void push(char elem) + { + resize(_length + 1); + _array[_length - 1] = elem; + } + + char& push() + { + resize(_length + 1); + return _array[_length - 1]; + } + + char& pop() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[--_length]; + } + + char& top() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + const char& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + char& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const char& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const char& value) + { + while (_length < newsize) + push(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + char* begin() + { + return _array; + } + + char* end() + { + return _array + _length; + } + + // Array-specific + void appendString(const char* str, bool keep_zero) + { + int len = (int)strlen(str); + int initial_size = _length; + + if (initial_size > 0 && _array[initial_size - 1] == 0) + initial_size--; + + resize(initial_size + len); + memcpy(_array + initial_size, str, len); + + if (keep_zero) + push(0); + } + + void readString(const char* str, bool keep_zero) + { + clear(); + appendString(str, keep_zero); + } + + void upper(const char* source) + { + clear(); + while (*source != 0) + push(::toupper(*source++)); + push(0); + } + + void lower(const char* source) + { + clear(); + while (*source != 0) + push(::tolower(*source++)); + push(0); + } + + void toupper() + { + for (int i = 0; i < _length; i++) + _array[i] = ::toupper(_array[i]); + } + + void tolower() + { + for (int i = 0; i < _length; i++) + _array[i] = ::tolower(_array[i]); + } + + protected: + char* _array; + int _reserved; + int _length; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(const Array& other) + { + copy(other); + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + int* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(int) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(int)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(int)); + } + + void fill(const int& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const int* ptr() const + { + return _array; + } + + int* ptr() + { + return _array; + } + + const int& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + int& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const int& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(int); + } + + void copy(const Array& other) + { + copy(other._array, other._length); + } + + void copy(const int* other, int count) + { + if (count > 0) + { + clear_resize(count); + memcpy(_array, other, count * sizeof(int)); + } + else + { + _length = 0; + } + } + + void concat(const Array& other) + { + concat(other._array, other.size()); + } + + void concat(const int* other, int count) + { + if (count > 0) + { + int length = _length; + resize(length + count); + + memcpy(_array + length, other, count * sizeof(int)); + } + } + + int memcmp(const Array& other) const + { + if (_length < other._length) + return -1; + if (_length > other._length) + return -1; + + if (_length == 0) + return 0; + + return ::memcmp(_array, other._array, _length * sizeof(int)); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(int) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int find(const int& value) const + { + return find(0, _length, value); + } + + int find(int from, int to, const int& value) const + { + for (int i = from; i < to; i++) + if (_array[i] == value) + return i; + + return -1; + } + + int count(const int& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const int& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + void push(int elem) + { + resize(_length + 1); + _array[_length - 1] = elem; + } + + int& push() + { + resize(_length + 1); + return _array[_length - 1]; + } + + int& emplace_back() + { + return push(); + } + + int& replace(int idx) + { + _array[idx] = 0; + return _array[idx]; + } + + int& pop() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[--_length]; + } + + int& top() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + const int& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + int& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const int& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const int& value) + { + while (_length < newsize) + push(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + int* begin() + { + return _array; + } + + int* end() + { + return _array + _length; + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void insertionSort(int start, int end, CmpFunctor cmp) + { + int i, j; + char tmp[sizeof(int)]; // can't use T directly because it may have destructor + + for (i = start + 1; i <= end; i++) + { + j = i; + while (j > start && cmp(_array[j - 1], _array[j]) > 0) + { + int* a1 = _array + j - 1; + int* a2 = a1 + 1; + memcpy(&tmp, a1, sizeof(int)); + memcpy(a1, a2, sizeof(int)); + memcpy(a2, &tmp, sizeof(int)); + j--; + } + } + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void qsort(int start, int end, CmpFunctor cmp) + { + // Sort elements from start to end + if (start >= end) + return; + if (end - start < 10) + insertionSort(start, end, cmp); + + struct + { + int *lo, *hi; + } stack[32], *sp; + + char tmp[sizeof(int)]; // can't use T directly because it may have destructor + + sp = stack; + + // push our initial values onto the stack + sp->lo = _array + start; + sp->hi = _array + end + 1; + sp++; + + while (sp > stack) + { + // pop lo and hi off the stack + sp--; + int *high = sp->hi, *low = sp->lo; + int* hi = high - 1; + int* lo = low; + int* pivot = low; + + while (1) + { + while (lo < high && lo != pivot && cmp(*lo, *pivot) < 0) + lo++; + + while (hi > low && (hi == pivot || cmp(*hi, *pivot) >= 0)) + hi--; + + if (lo < hi) + { + memcpy(&tmp, lo, sizeof(int)); + memcpy(lo, hi, sizeof(int)); + memcpy(hi, &tmp, sizeof(int)); + + if (lo == pivot) + pivot = hi; + else if (hi == pivot) + pivot = lo; + + hi--; + } + else + { + hi++; + + if (hi == high) + // done with this segment + break; + + // push the larger segment onto the stack and continue + // sorting the smaller segment. + if ((hi - low) > (high - hi)) + { + sp->lo = low; + sp->hi = hi; + sp++; + + hi = high; + low = lo; + } + else + { + sp->hi = high; + sp->lo = hi; + sp++; + + high = hi; + lo = low; + } + + pivot = lo; + hi--; + } + } + } + } + + template + void qsort(int start, int end, int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(start, end, _CmpFunctorCaller(cmp, context)); + } + + template + void qsort(int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(0, _length - 1, cmp, context); + } + + protected: + int* _array; + + int _reserved; + int _length; + + private: + template + class _CmpFunctorCaller + { + public: + _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + { + } + + int operator()(T1 arg1, T2 arg2) const + { + return _cmp(arg1, arg2, _context); + } + + private: + void* _context; + int (*_cmp)(T1, T2, void*); + }; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + byte* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(byte) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(byte)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(byte)); + } + + void fill(const byte& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const byte* ptr() const + { + return _array; + } + + byte* ptr() + { + return _array; + } + + const byte& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + byte& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const byte& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + byte& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(byte); + } + + void copy(const Array& other) + { + copy(other._array, other._length); + } + + void copy(const byte* other, int count) + { + if (count > 0) + { + clear_resize(count); + memcpy(_array, other, count * sizeof(byte)); + } + else + { + _length = 0; + } + } + + void concat(const Array& other) + { + concat(other._array, other.size()); + } + + void concat(const byte* other, int count) + { + if (count > 0) + { + int length = _length; + resize(length + count); + memcpy(_array + length, other, count * sizeof(byte)); + } + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(byte) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int count(const byte& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const byte& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + void push(byte elem) + { + resize(_length + 1); + _array[_length - 1] = elem; + } + + byte& push() + { + resize(_length + 1); + return _array[_length - 1]; + } + + void pop_back() + { + if (_length <= 0) + throw Error("stack underflow"); + --_length; + memset(_array + _length, 0, sizeof(byte)); + } + + byte& top() + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + const byte& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + byte& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const byte& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const byte& value) + { + while (_length < newsize) + push(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + byte* begin() + { + return _array; + } + + byte* end() + { + return _array + _length; + } + + protected: + byte* _array; + + int _reserved; + int _length; + + private: + void* _context; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + double* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(double) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(double)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(double)); + } + + void fill(const double& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const double* ptr() const + { + return _array; + } + + double* ptr() + { + return _array; + } + + const double& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + double& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const double& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + double& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(double); + } + + void copy(const Array& other) + { + clear_resize(0); + concat(other); + } + + void copy(const double* other, int count) + { + clear_resize(0); + for (int i = 0; i < count; ++i) + push_back(other[i]); + } + + void concat(const Array& other) + { + for (int i = 0; i < other.size(); ++i) + push_back(other[i]); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(double) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int count(const double& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const double& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + double& push_back(const double& elem) + { + resize(_length + 1); + new ((void*)&_array[_length - 1]) double(elem); + return _array[_length - 1]; + } + + void pop_back() + { + if (_length <= 0) + throw Error("stack underflow"); + --_length; + memset(_array + _length, 0, sizeof(double)); + } + + double& top() + { + if (_length <= 0) + throw Error("stack underflow"); + return _array[_length - 1]; + } + + const double& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + double& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const double& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const double& value) + { + while (_length < newsize) + push_back(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + double* begin() + { + return _array; + } + + double* end() + { + return _array + _length; + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void insertionSort(int start, int end, CmpFunctor cmp) + { + int i, j; + char tmp[sizeof(double)]; // can't use T directly because it may have destructor + + for (i = start + 1; i <= end; i++) + { + j = i; + while (j > start && cmp(_array[j - 1], _array[j]) > 0) + { + double* a1 = _array + j - 1; + double* a2 = a1 + 1; + memcpy(&tmp, a1, sizeof(double)); + memcpy(a1, a2, sizeof(double)); + memcpy(a2, &tmp, sizeof(double)); + j--; + } + } + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void qsort(int start, int end, CmpFunctor cmp) + { + // Sort elements from start to end + if (start >= end) + return; + if (end - start < 10) + insertionSort(start, end, cmp); + + struct + { + double *lo, *hi; + } stack[32], *sp; + + char tmp[sizeof(double)]; // can't use T directly because it may have destructor + + sp = stack; + + // push our initial values onto the stack + sp->lo = _array + start; + sp->hi = _array + end + 1; + sp++; + + while (sp > stack) + { + // pop lo and hi off the stack + sp--; + double *high = sp->hi, *low = sp->lo; + double* hi = high - 1; + double* lo = low; + double* pivot = low; + + while (1) + { + while (lo < high && lo != pivot && cmp(*lo, *pivot) < 0) + lo++; + + while (hi > low && (hi == pivot || cmp(*hi, *pivot) >= 0)) + hi--; + + if (lo < hi) + { + memcpy(&tmp, lo, sizeof(double)); + memcpy(lo, hi, sizeof(double)); + memcpy(hi, &tmp, sizeof(double)); + + if (lo == pivot) + pivot = hi; + else if (hi == pivot) + pivot = lo; + + hi--; + } + else + { + hi++; + + if (hi == high) + // done with this segment + break; + + // push the larger segment onto the stack and continue + // sorting the smaller segment. + if ((hi - low) > (high - hi)) + { + sp->lo = low; + sp->hi = hi; + sp++; + + hi = high; + low = lo; + } + else + { + sp->hi = high; + sp->lo = hi; + sp++; + + high = hi; + lo = low; + } + + pivot = lo; + hi--; + } + } + } + } + + template + void qsort(int start, int end, int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(start, end, _CmpFunctorCaller(cmp, context)); + } + + template + void qsort(int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(0, _length - 1, cmp, context); + } + + protected: + double* _array; + + int _reserved; + int _length; + + private: + Array(const Array&); // no implicit copy + Array& operator=(const Array& right); // no copy constructor + + template + class _CmpFunctorCaller + { + public: + _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + { + } + + int operator()(T1 arg1, T2 arg2) const + { + return _cmp(arg1, arg2, _context); + } + + private: + void* _context; + int (*_cmp)(T1, T2, void*); + }; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + float* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(float) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(float)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(float)); + } + + void fill(const float& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const float* ptr() const + { + return _array; + } + + float* ptr() + { + return _array; + } + + const float& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + float& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const float& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + float& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(float); + } + + void copy(const Array& other) + { + clear_resize(0); + concat(other); + } + + void copy(const float* other, int count) + { + clear_resize(0); + for (int i = 0; i < count; ++i) + push_back(other[i]); + } + + void concat(const Array& other) + { + for (int i = 0; i < other.size(); ++i) + push_back(other[i]); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(float) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int count(const float& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const float& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + float& push_back(const float& elem) + { + resize(_length + 1); + new ((void*)&_array[_length - 1]) float(elem); + return _array[_length - 1]; + } + + void pop_back() + { + if (_length <= 0) + throw Error("stack underflow"); + --_length; + memset(_array + _length, 0, sizeof(float)); + } + + float& top() + { + if (_length <= 0) + throw Error("stack underflow"); + return _array[_length - 1]; + } + + const float& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + float& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const float& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const float& value) + { + while (_length < newsize) + push_back(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + float* begin() + { + return _array; + } + + float* end() + { + return _array + _length; + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void insertionSort(int start, int end, CmpFunctor cmp) + { + int i, j; + char tmp[sizeof(float)]; // can't use T directly because it may have destructor + + for (i = start + 1; i <= end; i++) + { + j = i; + while (j > start && cmp(_array[j - 1], _array[j]) > 0) + { + float* a1 = _array + j - 1; + float* a2 = a1 + 1; + memcpy(&tmp, a1, sizeof(float)); + memcpy(a1, a2, sizeof(float)); + memcpy(a2, &tmp, sizeof(float)); + j--; + } + } + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void qsort(int start, int end, CmpFunctor cmp) + { + // Sort elements from start to end + if (start >= end) + return; + if (end - start < 10) + insertionSort(start, end, cmp); + + struct + { + float *lo, *hi; + } stack[32], *sp; + + char tmp[sizeof(float)]; // can't use T directly because it may have destructor + + sp = stack; + + // push our initial values onto the stack + sp->lo = _array + start; + sp->hi = _array + end + 1; + sp++; + + while (sp > stack) + { + // pop lo and hi off the stack + sp--; + float *high = sp->hi, *low = sp->lo; + float* hi = high - 1; + float* lo = low; + float* pivot = low; + + while (1) + { + while (lo < high && lo != pivot && cmp(*lo, *pivot) < 0) + lo++; + + while (hi > low && (hi == pivot || cmp(*hi, *pivot) >= 0)) + hi--; + + if (lo < hi) + { + memcpy(&tmp, lo, sizeof(float)); + memcpy(lo, hi, sizeof(float)); + memcpy(hi, &tmp, sizeof(float)); + + if (lo == pivot) + pivot = hi; + else if (hi == pivot) + pivot = lo; + + hi--; + } + else + { + hi++; + + if (hi == high) + // done with this segment + break; + + // push the larger segment onto the stack and continue + // sorting the smaller segment. + if ((hi - low) > (high - hi)) + { + sp->lo = low; + sp->hi = hi; + sp++; + + hi = high; + low = lo; + } + else + { + sp->hi = high; + sp->lo = hi; + sp++; + + high = hi; + lo = low; + } + + pivot = lo; + hi--; + } + } + } + } + + template + void qsort(int start, int end, int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(start, end, _CmpFunctorCaller(cmp, context)); + } + + template + void qsort(int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(0, _length - 1, cmp, context); + } + + protected: + float* _array; + + int _reserved; + int _length; + + template + class _CmpFunctorCaller + { + public: + _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + { + } + + int operator()(T1 arg1, T2 arg2) const + { + return _cmp(arg1, arg2, _context); + } + + private: + void* _context; + int (*_cmp)(T1, T2, void*); + }; + }; + + template <> + class Array + { + public: + DECL_TPL_ERROR(ArrayError); + + explicit Array() : _reserved(0), _length(0), _array(nullptr) + { + } + + Array(Array&& other) : _reserved(other._reserved), _length(other._length), _array(other._array) + { + other._array = nullptr; + other._length = 0; + other._reserved = 0; + } + + ~Array() + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + void clear() + { + _length = 0; + } + + void reserve(int to_reserve) + { + if (to_reserve < 0) + throw Error("to_reserve = %d", to_reserve); + + if (to_reserve > _reserved) + { + if (_length < 1) + { + if (_array != nullptr) + { + std::free(static_cast(_array)); + _array = nullptr; + _length = 0; + _reserved = 0; + } + } + + qword* oldptr = _array; + + _array = static_cast(std::realloc(static_cast(_array), sizeof(qword) * to_reserve)); + if (_array == nullptr) + { + _array = oldptr; + throw std::bad_alloc(); + } + _reserved = to_reserve; + } + } + + void zerofill() + { + if (_length > 0) + memset(_array, 0, _length * sizeof(qword)); + } + + void fffill() + { + if (_length > 0) + memset(_array, 0xFF, _length * sizeof(qword)); + } + + void fill(const qword& value) + { + for (int i = 0; i < size(); i++) + _array[i] = value; + } + + const qword* ptr() const + { + return _array; + } + + qword* ptr() + { + return _array; + } + + const qword& operator[](int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + qword& operator[](int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return _array[index]; + } + + const qword& at(int index) const + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + qword& at(int index) + { + if (index < 0 || _length - index <= 0) + throw Error("invalid index %d (size=%d)", index, _length); + + return (*this)[index]; + } + + int size() const + { + return _length; + } + + int sizeInBytes() const + { + return _length * sizeof(qword); + } + + void copy(const Array& other) + { + clear_resize(0); + concat(other); + } + + void copy(const qword* other, int count) + { + clear_resize(0); + for (int i = 0; i < count; ++i) + push_back(other[i]); + } + + void concat(const Array& other) + { + for (int i = 0; i < other.size(); ++i) + push_back(other[i]); + } + + void remove(int idx, int span = 1) + { + if (idx < 0 || idx - _length - span + 1 >= 0) + throw Error("remove(): invalid index %d with span %d (size=%d)", idx, span, _length); + + memmove(_array + idx, _array + idx + span, sizeof(qword) * (_length - idx - span)); + _length -= span; + } + + void remove_replace(int idx) + { + if (idx < 0 || idx >= _length) + throw Error("remove_replace(): invalid index %d (size=%d)", idx, _length); + + if (idx < _length - 1) + _array[idx] = _array[_length - 1]; + + _length--; + } + + int count(const qword& value) const + { + return count(0, _length, value); + } + + int count(int from, int to, const qword& value) const + { + int cnt = 0; + for (int i = from; i < to; i++) + if (_array[i] == value) + cnt++; + + return cnt; + } + + void swap(int idx1, int idx2) + { + if (idx1 < 0 || idx1 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx1, _length); + + if (idx2 < 0 || idx2 >= _length) + throw Error("swap(): invalid index %d (size=%d)", idx2, _length); + + if (idx1 == idx2) + return; + + std::swap(_array[idx1], _array[idx2]); + } + + qword& push_back(const qword& elem) + { + resize(_length + 1); + new ((void*)&_array[_length - 1]) qword(elem); + return _array[_length - 1]; + } + + void pop_back() + { + if (_length <= 0) + throw Error("stack underflow"); + --_length; + memset(_array + _length, 0, sizeof(qword)); + } + + qword& top() + { + if (_length <= 0) + throw Error("stack underflow"); + return _array[_length - 1]; + } + + const qword& top() const + { + if (_length <= 0) + throw Error("stack underflow"); + + return _array[_length - 1]; + } + + qword& top(int offset) + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + const qword& top(int offset) const + { + if (_length - offset <= 0) + throw Error("stack underflow"); + + return _array[_length - 1 - offset]; + } + + void resize(int newsize) + { + if (newsize > _reserved) + reserve((newsize + 1) * 2); + _length = newsize; + } + + void expand(int newsize) + { + if (_length < newsize) + resize(newsize); + } + + void expandFill(int newsize, const qword& value) + { + while (_length < newsize) + push_back(value); + } + + void clear_resize(int newsize) + { + if (_reserved < newsize) + { + _length = 0; + reserve((newsize + 1) * 2); + } + _length = newsize; + } + + void swap(Array& other) + { + std::swap(_array, other._array); + std::swap(_reserved, other._reserved); + std::swap(_length, other._length); + } + + qword* begin() + { + return _array; + } + + qword* end() + { + return _array + _length; + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void insertionSort(int start, int end, CmpFunctor cmp) + { + int i, j; + char tmp[sizeof(qword)]; // can't use T directly because it may have destructor + + for (i = start + 1; i <= end; i++) + { + j = i; + while (j > start && cmp(_array[j - 1], _array[j]) > 0) + { + qword* a1 = _array + j - 1; + qword* a2 = a1 + 1; + memcpy(&tmp, a1, sizeof(qword)); + memcpy(a1, a2, sizeof(qword)); + memcpy(a2, &tmp, sizeof(qword)); + j--; + } + } + } + + // CMP_FUNCTOR has two arguments and returns sign of comparation + template + void qsort(int start, int end, CmpFunctor cmp) + { + // Sort elements from start to end + if (start >= end) + return; + if (end - start < 10) + insertionSort(start, end, cmp); + + struct + { + qword *lo, *hi; + } stack[32], *sp; + + char tmp[sizeof(qword)]; // can't use T directly because it may have destructor + + sp = stack; + + // push our initial values onto the stack + sp->lo = _array + start; + sp->hi = _array + end + 1; + sp++; + + while (sp > stack) + { + // pop lo and hi off the stack + sp--; + qword *high = sp->hi, *low = sp->lo; + qword* hi = high - 1; + qword* lo = low; + qword* pivot = low; + + while (1) + { + while (lo < high && lo != pivot && cmp(*lo, *pivot) < 0) + lo++; + + while (hi > low && (hi == pivot || cmp(*hi, *pivot) >= 0)) + hi--; + + if (lo < hi) + { + memcpy(&tmp, lo, sizeof(qword)); + memcpy(lo, hi, sizeof(qword)); + memcpy(hi, &tmp, sizeof(qword)); + + if (lo == pivot) + pivot = hi; + else if (hi == pivot) + pivot = lo; + + hi--; + } + else + { + hi++; + + if (hi == high) + // done with this segment + break; + + // push the larger segment onto the stack and continue + // sorting the smaller segment. + if ((hi - low) > (high - hi)) + { + sp->lo = low; + sp->hi = hi; + sp++; + + hi = high; + low = lo; + } + else + { + sp->hi = high; + sp->lo = hi; + sp++; + + high = hi; + lo = low; + } + + pivot = lo; + hi--; + } + } + } + } + + template + void qsort(int start, int end, int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(start, end, _CmpFunctorCaller(cmp, context)); + } + + template + void qsort(int (*cmp)(T1, T2, void*), void* context) + { + this->qsort(0, _length - 1, cmp, context); + } + + protected: + qword* _array; + + int _reserved; + int _length; + + template + class _CmpFunctorCaller + { + public: + _CmpFunctorCaller(int (*cmp)(T1, T2, void*), void* context) : _context(context), _cmp(cmp) + { + } + + int operator()(T1 arg1, T2 arg2) const + { + return _cmp(arg1, arg2, _context); + } + + private: + void* _context; + int (*_cmp)(T1, T2, void*); }; }; - } // namespace indigo // operators defined here for use with ObjArray<> and ObjPool<> diff --git a/core/indigo-core/common/base_cpp/d_bitset.cpp b/core/indigo-core/common/base_cpp/d_bitset.cpp index b481b5a357..7b8ffd9856 100644 --- a/core/indigo-core/common/base_cpp/d_bitset.cpp +++ b/core/indigo-core/common/base_cpp/d_bitset.cpp @@ -123,6 +123,11 @@ Dbitset::Dbitset() _initWords(BITS_PER_WORD); } +Dbitset::Dbitset(const Dbitset& other) +{ + copy(other); +} + Dbitset::Dbitset(int nbits) { _initWords(nbits); diff --git a/core/indigo-core/common/base_cpp/d_bitset.h b/core/indigo-core/common/base_cpp/d_bitset.h index b8bfcdcfd7..7307461ff5 100644 --- a/core/indigo-core/common/base_cpp/d_bitset.h +++ b/core/indigo-core/common/base_cpp/d_bitset.h @@ -72,12 +72,12 @@ namespace indigo Array _words; - Dbitset(const Dbitset&); // no implicit copy - Dbitset& operator=(const Dbitset&); // no implicit assign public: Dbitset(); // creates a bit set whose initial size explicit Dbitset(int nbits); + Dbitset(const Dbitset& other); + ~Dbitset(); // sets the bit at the specified index to the complement of its current value diff --git a/core/indigo-core/common/base_cpp/list.h b/core/indigo-core/common/base_cpp/list.h index 5e58a68f99..01f6c9c327 100644 --- a/core/indigo-core/common/base_cpp/list.h +++ b/core/indigo-core/common/base_cpp/list.h @@ -33,6 +33,15 @@ namespace indigo int prev; int next; T item; + Elem(const Elem& other) + { + prev = other.prev; + next = other.next; + item = other.item; + } + Elem() + { + } }; explicit List() : _pool(new Pool), _size(0), _head(-1), _tail(-1), _own_pool(true) @@ -54,7 +63,7 @@ namespace indigo { if (_size == 0) { - _head = _pool->add(); + _head = _pool->emplace(); _tail = _head; Elem& elem = _pool->at(_head); @@ -64,7 +73,7 @@ namespace indigo } else { - int idx = _pool->add(); + int idx = _pool->emplace(); Elem& elem = _pool->at(idx); _pool->at(_tail).next = idx; @@ -89,7 +98,7 @@ namespace indigo { _pool->at(existing); // will throw if the element does not exist - int idx = _pool->add(); + int idx = _pool->emplace(); Elem& ex = _pool->at(existing); Elem& elem = _pool->at(idx); @@ -111,7 +120,7 @@ namespace indigo { _pool->at(existing); // will throw if the element does not exist - int idx = _pool->add(); + int idx = _pool->emplace(); Elem& ex = _pool->at(existing); Elem& elem = _pool->at(idx); @@ -220,9 +229,6 @@ namespace indigo int _head; int _tail; bool _own_pool; - - private: - List(const List&); // no implicit copy }; } // namespace indigo diff --git a/core/indigo-core/common/base_cpp/multimap.h b/core/indigo-core/common/base_cpp/multimap.h index cbd8615ef1..92c3e286fa 100644 --- a/core/indigo-core/common/base_cpp/multimap.h +++ b/core/indigo-core/common/base_cpp/multimap.h @@ -27,7 +27,7 @@ namespace indigo DECL_EXCEPTION(MultiMapError); template - class MultiMap : public NonCopyable + class MultiMap { public: DECL_TPL_ERROR(MultiMapError); diff --git a/core/indigo-core/common/base_cpp/non_copyable.h b/core/indigo-core/common/base_cpp/non_copyable.h deleted file mode 100644 index e7f338e4a3..0000000000 --- a/core/indigo-core/common/base_cpp/non_copyable.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * Copyright (C) from 2009 to Present EPAM Systems. - * - * This file is part of Indigo toolkit. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -#ifndef __non_copyable__ -#define __non_copyable__ - -namespace indigo -{ - - struct NonCopyable - { - NonCopyable() = default; - NonCopyable(const NonCopyable&) = delete; - NonCopyable& operator=(const NonCopyable&) = delete; - }; - -} // namespace indigo - -#endif diff --git a/core/indigo-core/common/base_cpp/obj_array.h b/core/indigo-core/common/base_cpp/obj_array.h index 3cfdcc05a7..c7a8009631 100644 --- a/core/indigo-core/common/base_cpp/obj_array.h +++ b/core/indigo-core/common/base_cpp/obj_array.h @@ -32,6 +32,11 @@ namespace indigo { } + ObjArray(const ObjArray& other) + { + copy(other); + } + ~ObjArray() { while (size() > 0) @@ -65,50 +70,35 @@ namespace indigo T& push() { - void* addr = &_array.push(); - - new (addr) T(); - + _array.emplace_back(); return _array.top(); } template T& push(A& a) { - void* addr = &_array.push(); - - new (addr) T(a); - + _array.emplace_back(a); return _array.top(); } template T& push(A& a, B* b) { - void* addr = &_array.push(); - - new (addr) T(a, b); - + void* addr = &_array.emplace_back(a, b); return _array.top(); } template T& push(A& a, B& b, C& c) { - void* addr = &_array.push(); - - new (addr) T(a, b, c); - + void* addr = &_array.emplace_back(a, b, c); return _array.top(); } template T& push(A* a, B b, C c) { - void* addr = &_array.push(); - - new (addr) T(a, b, c); - + void* addr = &_array.emplace_back(a, b, c); return _array.top(); } @@ -168,7 +158,7 @@ namespace indigo void pop() { _array.top().~T(); - _array.pop(); + _array.pop_back(); } template @@ -182,11 +172,13 @@ namespace indigo return _array.ptr(); } + void copy(const ObjArray& other) + { + _array.copy(other._array); + } + protected: Array _array; - - private: - ObjArray(const ObjArray&); // no implicit copy }; } // namespace indigo diff --git a/core/indigo-core/common/base_cpp/obj_pool.h b/core/indigo-core/common/base_cpp/obj_pool.h index 2bb7823c26..6d03212191 100644 --- a/core/indigo-core/common/base_cpp/obj_pool.h +++ b/core/indigo-core/common/base_cpp/obj_pool.h @@ -37,40 +37,8 @@ namespace indigo clear(); } - int add() - { - int idx = _pool.add(); - - void* addr = &_pool[idx]; - - new (addr) T(); - - return idx; - } - - template - int add(A& a) - { - int idx = _pool.add(); - - void* addr = &_pool[idx]; - - new (addr) T(a); - - return idx; - } - - template - int add(A& a, B& b) - { - int idx = _pool.add(); - - void* addr = &_pool[idx]; - - new (addr) T(a, b); - - return idx; - } + template + int add(Args&&... args); void remove(int idx) { @@ -139,6 +107,12 @@ namespace indigo ObjPool(const ObjPool&); // no implicit copy }; + template + template + int ObjPool::add(Args&&... args) + { + return _pool.emplace(std::forward(args)...); + } } // namespace indigo #endif diff --git a/core/indigo-core/common/base_cpp/os_thread_wrapper.cpp b/core/indigo-core/common/base_cpp/os_thread_wrapper.cpp index cadd453d5c..fa8bfd28c8 100644 --- a/core/indigo-core/common/base_cpp/os_thread_wrapper.cpp +++ b/core/indigo-core/common/base_cpp/os_thread_wrapper.cpp @@ -155,7 +155,10 @@ OsCommand* OsCommandDispatcher::_getVacantCommand() command->unique_id = _last_unique_command_id++; } else - command = _availableCommands.pop(); + { + command = _availableCommands.top(); + _availableCommands.pop_back(); + } command->clear(); @@ -169,9 +172,11 @@ OsCommandResult* OsCommandDispatcher::_getVacantResult() if (_availableResults.size() == 0) result = _allocateResult(); else - result = _availableResults.pop(); + { + result = _availableResults.top(); + _availableResults.pop_back(); + } result->clear(); - return result; } @@ -246,7 +251,7 @@ void OsCommandDispatcher::_onMsgHandleResult() throw Exception("cmdDispatcher::_OnMsgHandleResult: internal error #2"); OsSemaphore* sem = (OsSemaphore*)param; - _syspendedThreads.push(sem); + _syspendedThreads.push_back(sem); return; } diff --git a/core/indigo-core/common/base_cpp/pool.h b/core/indigo-core/common/base_cpp/pool.h index 651c659ca8..2e46c40150 100644 --- a/core/indigo-core/common/base_cpp/pool.h +++ b/core/indigo-core/common/base_cpp/pool.h @@ -37,11 +37,11 @@ namespace indigo { } - int add() + int add_item(const T& item) { if (_first == -1) { - _array.push(); + _array.push_back(item); _next.push(-2); _size++; @@ -57,18 +57,13 @@ namespace indigo _next[idx] = -2; _size++; - - return idx; - } - - int add(const T& item) - { - int idx = add(); - _array[idx] = item; return idx; } + template + int emplace(Args&&... args); + void remove(int idx) { if (_next[idx] != -2) @@ -164,6 +159,27 @@ namespace indigo Pool(const Pool&); // no implicit copy }; + template + template + int Pool::emplace(Args&&... args) + { + if (_first == -1) + { + _array.emplace_back(std::forward(args)...); + _next.push(-2); + _size++; + return _array.size() - 1; + } + int idx = _first; + _first = _next[_first]; + if (_first == -2) + throw Error("internal error: index %d is used in add()", idx); + _next[idx] = -2; + _size++; + _array.replace(idx, std::forward(args)...); + return idx; + } + } // namespace indigo #endif diff --git a/core/indigo-core/common/base_cpp/properties_map.cpp b/core/indigo-core/common/base_cpp/properties_map.cpp index 65a6283b77..222ab59f5e 100644 --- a/core/indigo-core/common/base_cpp/properties_map.cpp +++ b/core/indigo-core/common/base_cpp/properties_map.cpp @@ -22,6 +22,11 @@ using namespace indigo; IMPL_ERROR(PropertiesMap, "properties map"); +PropertiesMap::PropertiesMap(const PropertiesMap& other) +{ + copy(const_cast(other)); +} + void PropertiesMap::copy(RedBlackStringObjMap>& other) { clear(); diff --git a/core/indigo-core/common/base_cpp/ptr_array.h b/core/indigo-core/common/base_cpp/ptr_array.h index 47c7e90bbb..b9aec0befc 100644 --- a/core/indigo-core/common/base_cpp/ptr_array.h +++ b/core/indigo-core/common/base_cpp/ptr_array.h @@ -48,13 +48,15 @@ namespace indigo T& add(T* obj) { - _ptrarray.push(obj); + _ptrarray.push_back(obj); return *obj; } - T* pop(void) + void pop_back(void) { - return _ptrarray.pop(); + // assume the pointer is passed somewhere. + _ptrarray.top() = nullptr; + _ptrarray.pop_back(); } T* top(void) @@ -65,7 +67,7 @@ namespace indigo void expand(int newsize) { while (_ptrarray.size() < newsize) - _ptrarray.push(0); + _ptrarray.push_back(nullptr); } void clear(void) @@ -106,13 +108,13 @@ namespace indigo void removeLast() { - delete _ptrarray.pop(); + delete _ptrarray.top(); + _ptrarray.pop_back(); } void remove(int idx) { delete _ptrarray[idx]; - _ptrarray.remove(idx); } diff --git a/core/indigo-core/common/base_cpp/ptr_pool.h b/core/indigo-core/common/base_cpp/ptr_pool.h index 5cabd409ec..171324f6b9 100644 --- a/core/indigo-core/common/base_cpp/ptr_pool.h +++ b/core/indigo-core/common/base_cpp/ptr_pool.h @@ -48,7 +48,7 @@ namespace indigo int add(T* obj) { - return _ptrpool.add(obj); + return _ptrpool.add_item(obj); } void remove(int idx) diff --git a/core/indigo-core/common/base_cpp/red_black.h b/core/indigo-core/common/base_cpp/red_black.h index dafc8f837f..b2ba0cafdf 100644 --- a/core/indigo-core/common/base_cpp/red_black.h +++ b/core/indigo-core/common/base_cpp/red_black.h @@ -551,7 +551,7 @@ namespace indigo int _size; private: - RedBlackTree(const RedBlackTree&); // no implicit copy + RedBlackTree(const RedBlackTree&); }; template @@ -576,6 +576,13 @@ namespace indigo { } + RedBlackSet(const RedBlackSet& other) + { + Parent::clear(); + for (int i = other.begin(); i < other.end(); i = other.next(i)) + insert(other.key(i)); + } + ~RedBlackSet() override { } @@ -640,7 +647,7 @@ namespace indigo int _insert(Key key, int parent, int sign) { - int node_idx = this->_nodes->add(); + int node_idx = this->_nodes->emplace(); Node& node = this->_nodes->at(node_idx); node.key = key; @@ -649,14 +656,19 @@ namespace indigo return node_idx; } - - private: - RedBlackSet(const RedBlackSet&); // no implicit copy }; template struct RedBlackMapNode : public RedBlackNodeBase { + RedBlackMapNode(const RedBlackMapNode& other) : RedBlackNodeBase(other) + { + key = other.key; + value = other.value; + } + RedBlackMapNode() + { + } Key key; Value value; }; @@ -752,7 +764,7 @@ namespace indigo void _insert(Key key, Value value, int parent, int sign) { - int node_idx = this->_nodes->add(); + int node_idx = this->_nodes->emplace(); Node& node = this->_nodes->at(node_idx); node.key = key; @@ -780,6 +792,22 @@ namespace indigo public: typedef RedBlackStringMapNode Node; + RedBlackStringMap() + { + } + + RedBlackStringMap(const RedBlackStringMap& other) + { + copy(other); + } + + void copy(const RedBlackStringMap& other) + { + clear(); + for (int i = other.begin(); i != other.end(); i = other.next(i)) + this->insert(other.key(i), other.value(i)); + } + void clear() override { RedBlackTree::clear(); @@ -849,7 +877,7 @@ namespace indigo void _insert(const char* key, Value value, int parent, int sign) { int string_idx = _pool.add(key); - int node_idx = this->_nodes->add(); + int node_idx = this->_nodes->emplace(); Node& node = this->_nodes->at(node_idx); node.key_idx = string_idx; @@ -998,7 +1026,7 @@ namespace indigo Value* _insert(Key key, int parent, int sign) { - int node_idx = this->_nodes->add(); + int node_idx = this->_nodes->emplace(); Node& node = this->_nodes->at(node_idx); node.key = key; @@ -1046,6 +1074,11 @@ namespace indigo { } + RedBlackStringObjMap(const RedBlackStringObjMap& other) + { + copy(other); + } + ~RedBlackStringObjMap() override { this->clear(); @@ -1182,7 +1215,7 @@ namespace indigo int _insert(const char* key, int parent, int sign) { int string_idx = _pool.add(key); - int node_idx = this->_nodes->add(); + int node_idx = this->_nodes->emplace(); Node& node = this->_nodes->at(node_idx); node.key_idx = string_idx; @@ -1212,9 +1245,6 @@ namespace indigo } StringPool _pool; - - private: - RedBlackStringObjMap(const RedBlackStringObjMap&); // no implicit copy }; } // namespace indigo diff --git a/core/indigo-core/common/base_cpp/reusable_obj_array.h b/core/indigo-core/common/base_cpp/reusable_obj_array.h index 05a97d2ba8..fe0381c817 100644 --- a/core/indigo-core/common/base_cpp/reusable_obj_array.h +++ b/core/indigo-core/common/base_cpp/reusable_obj_array.h @@ -87,8 +87,7 @@ namespace indigo T* addr; if (_count == _array.size()) { - addr = &_array.push(); - new (addr) T(); + addr = &_array.emplace_back(); } else { diff --git a/core/indigo-core/common/base_cpp/string_pool.cpp b/core/indigo-core/common/base_cpp/string_pool.cpp index d555c5d17d..933a4fd9da 100644 --- a/core/indigo-core/common/base_cpp/string_pool.cpp +++ b/core/indigo-core/common/base_cpp/string_pool.cpp @@ -28,13 +28,19 @@ StringPool::StringPool() { } -StringPool::~StringPool() +StringPool::StringPool(const StringPool& other) { + _pool.clear(); + _storage.clear(); + for (int i = other.begin(); i != other.end(); i = other.next(i)) + { + add(other.at(i)); + } } int StringPool::_add(const char* str, int size) { - int idx = _pool.add(); + int idx = _pool.emplace(); // Save self into to the pool to check used items _pool[idx] = idx; diff --git a/core/indigo-core/common/base_cpp/string_pool.h b/core/indigo-core/common/base_cpp/string_pool.h index 8987576552..6f80b6dfbc 100644 --- a/core/indigo-core/common/base_cpp/string_pool.h +++ b/core/indigo-core/common/base_cpp/string_pool.h @@ -36,7 +36,7 @@ namespace indigo DECL_ERROR; StringPool(); - ~StringPool(); + StringPool(const StringPool& other); int add(const char* str); int add(Array& str); @@ -97,9 +97,6 @@ namespace indigo Pool _pool; PtrArray> _storage; - - private: - StringPool(const StringPool&); // no implicit copy }; } // namespace indigo diff --git a/core/indigo-core/common/base_cpp/tree.h b/core/indigo-core/common/base_cpp/tree.h index 3a9192efb6..b0e895e868 100644 --- a/core/indigo-core/common/base_cpp/tree.h +++ b/core/indigo-core/common/base_cpp/tree.h @@ -19,24 +19,37 @@ #ifndef __tree_h__ #define __tree_h__ -#include "non_copyable.h" #include "obj_array.h" namespace indigo { - class Tree : public NonCopyable + class Tree { + public: explicit Tree(int label) { this->label = label; } + explicit Tree(const Tree& other) + { + label = other.label; + _children.copy(other._children); + } + Tree() : Tree(-1) { } + Tree& operator=(const Tree& other) + { + label = other.label; + _children.copy(other._children); + return *this; + } + void insert(int label, int parent) { Tree* present = _find(parent); diff --git a/core/indigo-core/common/base_cpp/trie.h b/core/indigo-core/common/base_cpp/trie.h index e668622cb7..c119158c98 100644 --- a/core/indigo-core/common/base_cpp/trie.h +++ b/core/indigo-core/common/base_cpp/trie.h @@ -23,8 +23,6 @@ #include #include -#include "non_copyable.h" - namespace indigo { @@ -45,7 +43,7 @@ namespace indigo Currently, doesn't provide a delete/remove operation */ template - class Trie : public NonCopyable + class Trie { T _data; // A dataset associated with a given word diff --git a/core/indigo-core/common/lzw/lzw_decoder.cpp b/core/indigo-core/common/lzw/lzw_decoder.cpp index 8832c1e44f..48a78ff6ec 100644 --- a/core/indigo-core/common/lzw/lzw_decoder.cpp +++ b/core/indigo-core/common/lzw/lzw_decoder.cpp @@ -46,7 +46,11 @@ bool LzwDecoder::isEOF(void) int LzwDecoder::get(void) { if (_symbolsBuf.size()) - return _symbolsBuf.pop(); + { + int res = _symbolsBuf.top(); + _symbolsBuf.pop_back(); + return res; + } int NextCode; diff --git a/core/indigo-core/common/lzw/lzw_dictionary.cpp b/core/indigo-core/common/lzw/lzw_dictionary.cpp index 6b359f75ad..206f497daf 100644 --- a/core/indigo-core/common/lzw/lzw_dictionary.cpp +++ b/core/indigo-core/common/lzw/lzw_dictionary.cpp @@ -97,7 +97,6 @@ int LzwDict::getBitCodeSize(void) bool LzwDict::addElem(const int NewPrefix, const byte NewChar, int HashIndex) { int j; - _DictElement D(NewPrefix, NewChar); if (_nextCode <= _maxCode) { @@ -118,7 +117,7 @@ bool LzwDict::addElem(const int NewPrefix, const byte NewChar, int HashIndex) } } - _storage.push(D); + _storage.emplace_back(NewPrefix, NewChar); _freePtr++; diff --git a/core/indigo-core/common/lzw/lzw_dictionary.h b/core/indigo-core/common/lzw/lzw_dictionary.h index c6fab8f00d..7918308874 100644 --- a/core/indigo-core/common/lzw/lzw_dictionary.h +++ b/core/indigo-core/common/lzw/lzw_dictionary.h @@ -98,6 +98,10 @@ namespace indigo _DictElement(int NewPrefix, byte NewChar) : Prefix(NewPrefix), AppendChar(NewChar) { } + + _DictElement() : Prefix(0), AppendChar(0) + { + } }; int _hashingShift, /* Hashing function shift */ diff --git a/core/indigo-core/graph/automorphism_search.h b/core/indigo-core/graph/automorphism_search.h index b1be54eddd..101146a888 100644 --- a/core/indigo-core/graph/automorphism_search.h +++ b/core/indigo-core/graph/automorphism_search.h @@ -23,6 +23,7 @@ #include "base_cpp/reusable_obj_array.h" #include "base_cpp/tlscont.h" #include "graph/graph.h" +#include namespace indigo { @@ -30,6 +31,7 @@ namespace indigo class AutomorphismSearch { public: + using intpair = std::array; explicit AutomorphismSearch(); virtual ~AutomorphismSearch(); @@ -131,7 +133,7 @@ namespace indigo TL_CP_DECL(Array, _canonlab); TL_CP_DECL(Array, _orbits); TL_CP_DECL(Array, _fixedpts); - TL_CP_DECL(Array, _work_active_cells); + TL_CP_DECL(Array, _work_active_cells); TL_CP_DECL(Array, _edge_ranks_in_refine); int _n; diff --git a/core/indigo-core/graph/dfs_walk.h b/core/indigo-core/graph/dfs_walk.h index ea05578e5b..992b081482 100644 --- a/core/indigo-core/graph/dfs_walk.h +++ b/core/indigo-core/graph/dfs_walk.h @@ -33,6 +33,9 @@ namespace indigo public: struct SeqElem { + SeqElem(int index, int pv, int pe) : idx(index), parent_vertex(pv), parent_edge(pe) + { + } int idx; // index of vertex in _graph int parent_vertex; // parent vertex in DFS tree int parent_edge; // edge to parent vertex diff --git a/core/indigo-core/graph/graph.h b/core/indigo-core/graph/graph.h index fa3f2d6cb3..9c26b0e953 100644 --- a/core/indigo-core/graph/graph.h +++ b/core/indigo-core/graph/graph.h @@ -21,7 +21,6 @@ #include "base_cpp/array.h" #include "base_cpp/list.h" -#include "base_cpp/non_copyable.h" #include "base_cpp/obj_array.h" #include "base_cpp/obj_pool.h" #include "base_cpp/ptr_array.h" @@ -65,6 +64,9 @@ namespace indigo class DLLEXPORT Vertex { public: + Vertex() + { + } Vertex(Pool::Elem>& pool) : neighbors_list(pool) { } @@ -105,9 +107,6 @@ namespace indigo { return neighbors_list.size(); } - - private: - Vertex(const Vertex&); // no implicit copy }; struct Edge @@ -123,11 +122,19 @@ namespace indigo return beg; return -1; } + + Edge() : beg(-1), end(-1) + { + } + + Edge(int begin, int end) : beg(begin), end(end) + { + } }; class CycleBasis; - class DLLEXPORT Graph : public NonCopyable + class DLLEXPORT Graph { public: DECL_ERROR; diff --git a/core/indigo-core/graph/src/automorphism_search.cpp b/core/indigo-core/graph/src/automorphism_search.cpp index 1443ccba79..fc944fd287 100644 --- a/core/indigo-core/graph/src/automorphism_search.cpp +++ b/core/indigo-core/graph/src/automorphism_search.cpp @@ -287,7 +287,7 @@ void AutomorphismSearch::process(Graph& graph) for (i = 0; i < _n; ++i) _orbits[i] = i; - _Call& call = _call_stack.push(); + _Call& call = _call_stack.emplace_back(); call.level = 1; call.numcells = numcells; call.place = _INITIAL; @@ -303,7 +303,7 @@ void AutomorphismSearch::process(Graph& graph) { retval = _firstNode(call.level, call.numcells); if (retval >= 0) - _call_stack.pop(); + _call_stack.pop_back(); } else if (call.place == _FIRST_LOOP) { @@ -320,7 +320,7 @@ void AutomorphismSearch::process(Graph& graph) if (retval < call.level) { - _call_stack.pop(); + _call_stack.pop_back(); continue; // break the _FIRST_LOOP and keep the retval; } @@ -346,7 +346,7 @@ void AutomorphismSearch::process(Graph& graph) { // return from _FIRST_LOOP retval = call.level - 1; - _call_stack.pop(); + _call_stack.pop_back(); continue; } @@ -356,7 +356,7 @@ void AutomorphismSearch::process(Graph& graph) _cosetindex = tv; _fixedpts[tv] = 1; - _Call& newcall = _call_stack.push(); + _Call& newcall = _call_stack.emplace_back(); newcall.level = call.level + 1; newcall.numcells = call.numcells + 1; if (tv == call.tv1) @@ -373,7 +373,7 @@ void AutomorphismSearch::process(Graph& graph) if (retval >= 0) // _FIRST_LOOP did not happen; pass the return value to the caller - _call_stack.pop(); + _call_stack.pop_back(); } else if (call.place == _FIRST_TO_OTHER || call.place == _OTHER_TO_OTHER) { @@ -381,7 +381,7 @@ void AutomorphismSearch::process(Graph& graph) if (retval >= 0) // _OTHER_LOOP did not happen; pass the return value to the caller - _call_stack.pop(); + _call_stack.pop_back(); } else if (call.place == _OTHER_LOOP) { @@ -396,7 +396,7 @@ void AutomorphismSearch::process(Graph& graph) if (retval < call.level) { - _call_stack.pop(); + _call_stack.pop_back(); continue; // break the _OTHER_LOOP and keep the retval; } @@ -419,7 +419,7 @@ void AutomorphismSearch::process(Graph& graph) { // return from _OTHER_LOOP retval = call.level - 1; - _call_stack.pop(); + _call_stack.pop_back(); continue; } @@ -430,7 +430,7 @@ void AutomorphismSearch::process(Graph& graph) _breakout(call.level + 1, call.tc, tv); _fixedpts[tv] = 1; - _Call& newcall = _call_stack.push(); + _Call& newcall = _call_stack.emplace_back(); newcall.level = call.level + 1; newcall.numcells = call.numcells + 1; newcall.place = _OTHER_TO_OTHER; @@ -468,10 +468,10 @@ int AutomorphismSearch::_firstNode(int level, int numcells) int tc = _targetcell(level, _tcells[level]); int tv1 = _tcells[level][0]; - _call_stack.pop(); + _call_stack.pop_back(); // use the elements of the target cell to produce the children - _Call& call = _call_stack.push(); + _Call& call = _call_stack.emplace_back(); call.level = level; call.k = 0; call.tc = tc; @@ -503,10 +503,10 @@ int AutomorphismSearch::_otherNode(int level, int numcells) int tv1 = _tcells[level][0]; - _call_stack.pop(); + _call_stack.pop_back(); // use the elements of the target cell to produce the children - _Call& call = _call_stack.push(); + _Call& call = _call_stack.emplace_back(); call.level = level; call.k = 0; call.tc = tc; @@ -918,10 +918,8 @@ void AutomorphismSearch::_refineBySortingNeighbourhood(int level, int& numcells) for (split2 = split1; _ptn[split2] > level; split2++) ; - int(&split_cell)[2] = _work_active_cells.push(); - split_cell[0] = split1; - split_cell[1] = split2; - + std::array split_cell{split1, split2}; + _work_active_cells.push_back(split_cell); _active[i] = 0; } } @@ -932,7 +930,7 @@ void AutomorphismSearch::_refineBySortingNeighbourhood(int level, int& numcells) // Refine all cells by collected active cells for (int i = 0; i < _work_active_cells.size(); i++) { - int(&split_cell)[2] = _work_active_cells[i]; + intpair& split_cell = _work_active_cells[i]; int split1 = split_cell[0], split2 = split_cell[1]; diff --git a/core/indigo-core/graph/src/biconnected_decomposer.cpp b/core/indigo-core/graph/src/biconnected_decomposer.cpp index 26ef688858..56423b4459 100644 --- a/core/indigo-core/graph/src/biconnected_decomposer.cpp +++ b/core/indigo-core/graph/src/biconnected_decomposer.cpp @@ -152,7 +152,7 @@ bool BiconnectedDecomposer::_pushToStack(Array& dfs_stack, int v) new_edge.beg = v; new_edge.end = w; - _edges_stack.push(new_edge); + _edges_stack.push_back(new_edge); dfs_stack.push(w); _cur_order++; @@ -163,7 +163,7 @@ bool BiconnectedDecomposer::_pushToStack(Array& dfs_stack, int v) { new_edge.beg = v; new_edge.end = w; - _edges_stack.push(new_edge); + _edges_stack.push_back(new_edge); if (_lowest_order[v] > _dfs_order[w]) _lowest_order[v] = _dfs_order[w]; @@ -198,11 +198,11 @@ void BiconnectedDecomposer::_processIfNotPushed(Array& dfs_stack, int w) { _components[cur_comp]->at(_edges_stack.top().beg) = 1; _components[cur_comp]->at(_edges_stack.top().end) = 1; - _edges_stack.pop(); + _edges_stack.pop_back(); } _components[cur_comp]->at(v) = 1; _components[cur_comp]->at(w) = 1; - _edges_stack.pop(); + _edges_stack.pop_back(); } } diff --git a/core/indigo-core/graph/src/dfs_walk.cpp b/core/indigo-core/graph/src/dfs_walk.cpp index e04d5f41e4..ae3f36466c 100644 --- a/core/indigo-core/graph/src/dfs_walk.cpp +++ b/core/indigo-core/graph/src/dfs_walk.cpp @@ -95,13 +95,7 @@ void DfsWalk::walk() int v_idx = v_stack.pop(); int parent_vertex = _vertices[v_idx].parent_vertex; - { - SeqElem& seq_elem = _v_seq.push(); - - seq_elem.idx = v_idx; - seq_elem.parent_vertex = parent_vertex; - seq_elem.parent_edge = _vertices[v_idx].parent_edge; - } + SeqElem& seq_elem = _v_seq.emplace_back(v_idx, parent_vertex, _vertices[v_idx].parent_edge); _vertices[v_idx].dfs_state = 2; @@ -119,10 +113,7 @@ void DfsWalk::walk() if (_root_vertices[nei_v] == 1 && _vertices[nei_v].dfs_state == 0) continue; - VertexEdge& ve = nei.push(); - - ve.e = vertex.neiEdge(i); - ve.v = nei_v; + VertexEdge& ve = nei.emplace_back(nei_v, vertex.neiEdge(i)); } if (vertex_ranks != 0) @@ -146,18 +137,11 @@ void DfsWalk::walk() if (_vertices[nei_idx].dfs_state == 2) { _edges[edge_idx].closing_cycle = 1; - Edge& e = _closures.push(); - e.beg = v_idx; - e.end = nei_idx; + Edge& e = _closures.emplace_back(v_idx, nei_idx); _vertices[nei_idx].openings++; _vertices[v_idx].branches++; - - SeqElem& seq_elem = _v_seq.push(); - - seq_elem.idx = nei_idx; - seq_elem.parent_vertex = v_idx; - seq_elem.parent_edge = edge_idx; + SeqElem& seq_elem = _v_seq.emplace_back(nei_idx, v_idx, edge_idx); } else { diff --git a/core/indigo-core/graph/src/edge_rotation_matcher.cpp b/core/indigo-core/graph/src/edge_rotation_matcher.cpp index d7c2e3994c..67dfe6c2a4 100644 --- a/core/indigo-core/graph/src/edge_rotation_matcher.cpp +++ b/core/indigo-core/graph/src/edge_rotation_matcher.cpp @@ -69,12 +69,12 @@ bool EdgeRotationMatcher::match(float rms_threshold, float eps) if (_mapping[edge.beg] < 0 || _mapping[edge.end] < 0) continue; - edge_queue.push(); + edge_queue.emplace_back(); edge_queue.top().idx = i; edge_queue.top().beg = edge.beg; edge_queue.top().end = edge.end; - edge_queue.push(); + edge_queue.emplace_back(); edge_queue.top().idx = i; edge_queue.top().beg = edge.end; edge_queue.top().end = edge.beg; @@ -142,8 +142,8 @@ bool EdgeRotationMatcher::match(float rms_threshold, float eps) if (_mapping[i] < 0) continue; - Vec3f& pos_sub = xyz_sub.push(); - Vec3f& pos_super = xyz_super.push(); + Vec3f& pos_sub = xyz_sub.emplace_back(); + Vec3f& pos_super = xyz_super.emplace_back(); cb_get_xyz(_subgraph, i, pos_sub); cb_get_xyz(_supergraph, _mapping[i], pos_super); @@ -188,7 +188,7 @@ bool EdgeRotationMatcher::match(float rms_threshold, float eps) states[nei_edge_idx] = 1; // push the neighbor edge to the queue - edge_queue.push(); + edge_queue.emplace_back(); edge_queue.top().idx = nei_edge_idx; edge_queue.top().beg = edge_end; edge_queue.top().end = other_end; diff --git a/core/indigo-core/graph/src/embedding_enumerator.cpp b/core/indigo-core/graph/src/embedding_enumerator.cpp index 559d15dd02..d1ee64b453 100644 --- a/core/indigo-core/graph/src/embedding_enumerator.cpp +++ b/core/indigo-core/graph/src/embedding_enumerator.cpp @@ -182,12 +182,12 @@ void EmbeddingEnumerator::processStart() } } - _query_match_state.push(_QuertMatchState(node1, parent, _t1_len_pre)); + _query_match_state.emplace_back(node1, parent, _t1_len_pre); _fixNode1(node1, FIX_MARK); } // Push last element to indicate the end of query atoms queue - _query_match_state.push(_QuertMatchState(-1, -1, -1)); + _query_match_state.emplace_back(-1, -1, -1); // Restore core_1 _core_1.copy(core1_pre); diff --git a/core/indigo-core/graph/src/embeddings_storage.cpp b/core/indigo-core/graph/src/embeddings_storage.cpp index 786f1c6fd9..8f3bd6f4e4 100644 --- a/core/indigo-core/graph/src/embeddings_storage.cpp +++ b/core/indigo-core/graph/src/embeddings_storage.cpp @@ -47,7 +47,7 @@ bool GraphEmbeddingsStorage::addEmbedding(const Graph& super, const Graph& sub, { // Add new item to the storage // If it isn't unque then remove it - _EmbeddingData& data = _embedding_data.push(); + _EmbeddingData& data = _embedding_data.emplace_back(); int added_index = _embedding_data.size() - 1; data.vertex_begin = _all_vertices.size(); data.edge_begin = _all_edges.size(); @@ -104,7 +104,7 @@ bool GraphEmbeddingsStorage::addEmbedding(const Graph& super, const Graph& sub, _all_vertices.resize(data.vertex_begin); _all_edges.resize(data.edge_begin); _all_mappings.resize(data.sub_mapping_begin); - _embedding_data.pop(); + _embedding_data.pop_back(); return false; } if (_embedding_data[cur].next == -1) diff --git a/core/indigo-core/graph/src/graph.cpp b/core/indigo-core/graph/src/graph.cpp index d5f007f2c8..bbf7732a9a 100644 --- a/core/indigo-core/graph/src/graph.cpp +++ b/core/indigo-core/graph/src/graph.cpp @@ -122,7 +122,7 @@ int Graph::addEdge(int beg, int end) if (findEdgeIndex(beg, end) != -1) throw Error("already have edge between vertices %d and %d", beg, end); - int edge_idx = _edges.add(); + int edge_idx = _edges.emplace(); Vertex& vbeg = _vertices->at(beg); Vertex& vend = _vertices->at(end); @@ -800,7 +800,7 @@ void Graph::_cloneGraph_KeepIndices(const Graph& other) throw Error("_clone_KeepIndices: internal"); for (i = 0; i <= max_edge_idx; i++) - if (_edges.add() != i) + if (_edges.emplace() != i) throw Error("_clone_KeepIndices: unexpected edge index"); i_prev = -1; diff --git a/core/indigo-core/graph/src/graph_affine_matcher.cpp b/core/indigo-core/graph/src/graph_affine_matcher.cpp index d32429cef4..1c84e40070 100644 --- a/core/indigo-core/graph/src/graph_affine_matcher.cpp +++ b/core/indigo-core/graph/src/graph_affine_matcher.cpp @@ -53,9 +53,9 @@ bool GraphAffineMatcher::match(float rms_threshold) if (_mapping[fixed_vertices->at(i)] < 0) continue; cb_get_xyz(_subgraph, fixed_vertices->at(i), pos); - points.push(pos); + points.push_back(pos); cb_get_xyz(_supergraph, _mapping[fixed_vertices->at(i)], pos); - goals.push(pos); + goals.push_back(pos); } } else @@ -64,9 +64,9 @@ bool GraphAffineMatcher::match(float rms_threshold) if (_mapping[i] < 0) continue; cb_get_xyz(_subgraph, i, pos); - points.push(pos); + points.push_back(pos); cb_get_xyz(_supergraph, _mapping[i], pos); - goals.push(pos); + goals.push_back(pos); } if (points.size() < 1) diff --git a/core/indigo-core/graph/src/graph_subtree_enumerator.cpp b/core/indigo-core/graph/src/graph_subtree_enumerator.cpp index 7f58bfeea9..a92df5121c 100644 --- a/core/indigo-core/graph/src/graph_subtree_enumerator.cpp +++ b/core/indigo-core/graph/src/graph_subtree_enumerator.cpp @@ -104,7 +104,7 @@ void GraphSubtreeEnumerator::_reverseSearch(int front_idx, int cur_maximal_crite if (_v_processed[nei_v] == 1) continue; - VertexEdgeParent& added = _front.push(); + VertexEdgeParent& added = _front.emplace_back(); added.v = nei_v; added.e = vertex.neiEdge(i); added.parent = v; @@ -114,7 +114,7 @@ void GraphSubtreeEnumerator::_reverseSearch(int front_idx, int cur_maximal_crite if (front_size < new_front_size) { _front[front_idx] = _front.top(); - _front.pop(); + _front.pop_back(); new_front_size--; } diff --git a/core/indigo-core/graph/src/path_enumerator.cpp b/core/indigo-core/graph/src/path_enumerator.cpp index d6a46562c6..46e6f0efff 100644 --- a/core/indigo-core/graph/src/path_enumerator.cpp +++ b/core/indigo-core/graph/src/path_enumerator.cpp @@ -49,14 +49,14 @@ void PathEnumerator::process() vertices.clear(); edges.clear(); flags.clear_resize(_graph.vertexEnd()); - flags.zerofill(); + flags.fill(false); vertices.push(_begin); edges.push(-1); // fictitious edge flags[_begin] = true; index.clear_resize(_graph.vertexEnd()); index.zerofill(); can_achieve_to_end.clear_resize(_graph.vertexEnd()); - can_achieve_to_end.zerofill(); + can_achieve_to_end.fill(false); can_achieve_to_end[_end] = true; index[_begin] = _graph.getVertex(_begin).neiBegin(); diff --git a/core/indigo-core/graph/src/spanning_tree.cpp b/core/indigo-core/graph/src/spanning_tree.cpp index ff7603ddf5..010d16f276 100644 --- a/core/indigo-core/graph/src/spanning_tree.cpp +++ b/core/indigo-core/graph/src/spanning_tree.cpp @@ -72,7 +72,7 @@ SpanningTree::SpanningTree(Graph& graph, const Filter* vertex_filter, const Filt if (start == _tree.vertexEnd()) break; - StackElem& elem = _stack.push(); + StackElem& elem = _stack.emplace_back(); elem.vertex = &_graph.getVertex(_mapping[start]); elem.nei_idx = elem.vertex->neiBegin(); elem.vertex_idx = start; @@ -114,7 +114,7 @@ void SpanningTree::_build() _edge_mapping[idx] = elem.vertex->neiEdge(i); - StackElem& newelem = _stack.push(); + StackElem& newelem = _stack.emplace_back(); _depth_counters[w] = ++_current_depth; newelem.parent_idx = v; @@ -131,11 +131,11 @@ void SpanningTree::_build() edge.ext_beg_idx = _mapping[v]; edge.ext_end_idx = _mapping[w]; edge.ext_edge_idx = elem.vertex->neiEdge(i); - _edges_list.push(edge); + _edges_list.push_back(edge); } } else - _stack.pop(); + _stack.pop_back(); } } diff --git a/core/indigo-core/layout/layout_pattern.h b/core/indigo-core/layout/layout_pattern.h index 70c603b583..416c6326f7 100644 --- a/core/indigo-core/layout/layout_pattern.h +++ b/core/indigo-core/layout/layout_pattern.h @@ -34,6 +34,10 @@ namespace indigo struct PatternAtom { + PatternAtom() : pos(0, 0) + { + } + explicit PatternAtom(Vec2f pos_) : pos(pos_) { } @@ -42,6 +46,10 @@ namespace indigo struct PatternBond { + PatternBond() : type(0), parity(0) + { + } + explicit PatternBond(int type_) : type(type_), parity(0) { } diff --git a/core/indigo-core/layout/molecule_cleaner_2d.h b/core/indigo-core/layout/molecule_cleaner_2d.h index 83198ffd1f..e5e782c1df 100644 --- a/core/indigo-core/layout/molecule_cleaner_2d.h +++ b/core/indigo-core/layout/molecule_cleaner_2d.h @@ -20,7 +20,6 @@ #define __molecule_cleaner_2d__ #include "base_cpp/array.h" -#include "base_cpp/non_copyable.h" #include "base_cpp/obj_array.h" #include "common/math/algebra.h" @@ -28,7 +27,7 @@ namespace indigo { class BaseMolecule; - class DLLEXPORT MoleculeCleaner2d : public NonCopyable + class DLLEXPORT MoleculeCleaner2d { public: diff --git a/core/indigo-core/layout/src/layout_pattern.cpp b/core/indigo-core/layout/src/layout_pattern.cpp index 9a5007258e..7fa03582b4 100644 --- a/core/indigo-core/layout/src/layout_pattern.cpp +++ b/core/indigo-core/layout/src/layout_pattern.cpp @@ -55,7 +55,7 @@ int PatternLayout::addBond(int atom_beg, int atom_end, int type) int PatternLayout::addOutlinePoint(float x, float y) { - Vec2f& p = _outline.push(); + Vec2f& p = _outline.emplace_back(); p.set(x, y); diff --git a/core/indigo-core/layout/src/molecule_cleaner_2d.cpp b/core/indigo-core/layout/src/molecule_cleaner_2d.cpp index ba9ed2f423..07cbde222f 100644 --- a/core/indigo-core/layout/src/molecule_cleaner_2d.cpp +++ b/core/indigo-core/layout/src/molecule_cleaner_2d.cpp @@ -83,7 +83,7 @@ MoleculeCleaner2d::MoleculeCleaner2d(BaseMolecule& mol, bool use_biconnected_dec void MoleculeCleaner2d::_initBasePointValid() { is_valid_base.clear_resize(vertex_size); - is_valid_base.zerofill(); + is_valid_base.fill(false); for (int v = _mol.vertexBegin(); v != _mol.vertexEnd(); v = _mol.vertexNext(v)) is_valid_base[v] = is_art_point[v] || _mol.getVertex(v).degree() == 1; } @@ -109,12 +109,12 @@ void MoleculeCleaner2d::_initComponents(bool use_beconnected_decomposition) { in.push(); in.top().clear_resize(vertex_size); - in.top().zerofill(); + in.top().fill(false); } Filter filter; _is_trivial.clear_resize(component_count); - _is_trivial.zerofill(); + _is_trivial.fill(false); for (int i = 0; i < component_count; i++) { @@ -137,7 +137,7 @@ void MoleculeCleaner2d::_initComponents(bool use_beconnected_decomposition) { in.push(); in.top().clear_resize(vertex_size); - in.top().zerofill(); + in.top().fill(false); } _is_trivial.clear_resize(component_count); @@ -175,12 +175,12 @@ void MoleculeCleaner2d::_initComponents(bool use_beconnected_decomposition) QS_DEF(Array, has_vertex); QS_DEF(Array, block_vertex); has_component.clear_resize(component_count); - has_component.zerofill(); + has_component.fill(false); component_list.clear(); has_vertex.clear_resize(vertex_size); - has_vertex.zerofill(); + has_vertex.fill(false); block_vertex.clear_resize(vertex_size); - block_vertex.zerofill(); + block_vertex.fill(false); QS_DEF(Array, local_component_list); @@ -361,7 +361,7 @@ void MoleculeCleaner2d::_uniteBondsOnLine() unite_with[i] = i; _is_straightline_vertex.clear_resize(vertex_size); - _is_straightline_vertex.zerofill(); + _is_straightline_vertex.fill(false); QS_DEF(ObjArray>, unite_to); unite_to.clear(); @@ -450,7 +450,7 @@ void MoleculeCleaner2d::_uniteBondsOnLine() QS_DEF(Array, valid); valid.clear_resize(component_count); - valid.zerofill(); + valid.fill(false); for (int i = 0; i < component_count; i++) valid[unite_with[i]] = true; @@ -520,7 +520,7 @@ void MoleculeCleaner2d::_initGeometry() void MoleculeCleaner2d::_initArtPoints() { is_art_point.clear_resize(vertex_size); - is_art_point.zerofill(); + is_art_point.fill(false); for (int i = _mol.vertexBegin(); i != _mol.vertexEnd(); i = _mol.vertexNext(i)) { int cnt = 0; @@ -540,7 +540,7 @@ void MoleculeCleaner2d::_initAdjMatrix() { adj_matrix.push(); adj_matrix.top().clear_resize(vertex_size); - adj_matrix.top().zerofill(); + adj_matrix.top().fill(false); } for (int e = _mol.edgeBegin(); e != _mol.edgeEnd(); e = _mol.edgeNext(e)) { @@ -599,7 +599,7 @@ void MoleculeCleaner2d::_initCommonBiconnectedComp() decomposer.getComponent(i, filter); b_in.push(); b_in[i].clear_resize(vertex_size); - b_in[i].zerofill(); + b_in[i].fill(false); for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j)) { b_in[i][j] = filter.valid(j); @@ -628,7 +628,7 @@ bool MoleculeCleaner2d::_isBasePoint(int i) void MoleculeCleaner2d::_addCoef(int ver, int index, Vec2f value) { while (coef[ver].size() <= index) - coef[ver].push(ZERO); + coef[ver].push_back(ZERO); coef[ver][index] += value; } @@ -933,7 +933,7 @@ float MoleculeCleaner2d::_energy() int v = vert.neiVertex(n1); Vec2f vec = pos[v] - pos[i]; float alpha = atan2(vec.y, vec.x); - angles.push(alpha); + angles.push_back(alpha); } for (int a = 0; a < angles.size(); a++) @@ -941,7 +941,7 @@ float MoleculeCleaner2d::_energy() if (angles[b + 1] < angles[b]) std::swap(angles[b], angles[b + 1]); - angles.push(_2FLOAT(angles[0] + 2. * M_PI)); + angles.push_back(_2FLOAT(angles[0] + 2. * M_PI)); if (vert.degree() > 2) { float target_angle = _2FLOAT(2. * M_PI / angles.size()); diff --git a/core/indigo-core/layout/src/molecule_layout.cpp b/core/indigo-core/layout/src/molecule_layout.cpp index 8c10d4659e..e54504d84d 100644 --- a/core/indigo-core/layout/src/molecule_layout.cpp +++ b/core/indigo-core/layout/src/molecule_layout.cpp @@ -117,7 +117,7 @@ void _collectCrossBonds(Array& crossBonds, Array& crossBondOut, BaseM } } -void _placeSGroupBracketsCrossBonds(Array& brackets, BaseMolecule& mol, const Array& atoms, const Array& crossBonds, +void _placeSGroupBracketsCrossBonds(Array>& brackets, BaseMolecule& mol, const Array& atoms, const Array& crossBonds, const Array& crossBondOut, float bondLength) { brackets.clear(); @@ -181,18 +181,16 @@ void _placeSGroupBracketsCrossBonds(Array& brackets, BaseMolecule& mol float factor = 0.5; b1.addScaled(n, factor * bondLength); b2.addScaled(n, -factor * bondLength); - Vec2f* const& bracket1 = brackets.push(); - bracket1[0].copy(b1); - bracket1[1].copy(b2); + std::array bracket1{b1, b2}; + brackets.push_back(bracket1); b1.copy(c); b1.addScaled(d, min.x - 0.3f * bondLength); b2.copy(b1); b1.addScaled(n, -factor * bondLength); b2.addScaled(n, factor * bondLength); - Vec2f* const& bracket2 = brackets.push(); - bracket2[0].copy(b1); - bracket2[1].copy(b2); + std::array bracket2{b1, b2}; + brackets.push_back(bracket2); return; } } @@ -219,13 +217,13 @@ void _placeSGroupBracketsCrossBonds(Array& brackets, BaseMolecule& mol float factor = 0.5; b1.addScaled(n, factor * bondLength); b2.addScaled(n, -factor * bondLength); - Vec2f* const& bracket = brackets.push(); - bracket[0].copy(b1); - bracket[1].copy(b2); + + std::array bracket{b1, b2}; + brackets.push_back(bracket); } } -void _placeSGroupBracketsCrossBondSingle(Array& brackets, BaseMolecule& mol, const Array& atoms, int bid, bool out, float bondLength) +void _placeSGroupBracketsCrossBondSingle(Array>& brackets, BaseMolecule& mol, const Array& atoms, int bid, bool out, float bondLength) { brackets.clear(); const Edge& edge = mol.getEdge(bid); @@ -270,20 +268,18 @@ void _placeSGroupBracketsCrossBondSingle(Array& brackets, BaseMolecule float factor = 0.5; b1.addScaled(n, factor * bondLength); b2.addScaled(n, -factor * bondLength); - Vec2f* const& bracket1 = brackets.push(); - bracket1[0].copy(b1); - bracket1[1].copy(b2); + std::array bracket1{b1, b2}; + brackets.push_back(bracket1); b1.lineCombin(p2dIn, d, min.x - 0.3f * bondLength); b2.copy(b1); b1.addScaled(n, -factor * bondLength); b2.addScaled(n, factor * bondLength); - Vec2f* const& bracket2 = brackets.push(); - bracket2[0].copy(b1); - bracket2[1].copy(b2); + std::array bracket2{b1, b2}; + brackets.push_back(bracket2); } -void _placeSGroupBracketsHorizontal(Array& brackets, BaseMolecule& mol, const Array& atoms, float bondLength) +void _placeSGroupBracketsHorizontal(Array>& brackets, BaseMolecule& mol, const Array& atoms, float bondLength) { brackets.clear(); Vec2f min, max, a, b; @@ -309,12 +305,12 @@ void _placeSGroupBracketsHorizontal(Array& brackets, BaseMolecule& mol min.sub(Vec2f(extent, extent)); max.add(Vec2f(extent, extent)); - Vec2f* const& left = brackets.push(); - left[0].set(min.x, min.y); - left[1].set(min.x, max.y); - Vec2f* const& right = brackets.push(); - right[0].set(max.x, max.y); - right[1].set(max.x, min.y); + // brackets.emplace_back(min.x, min.y,min.x, max.y,max.x, max.y,max.x, min.y); change later + std::array left{Vec2f(min.x, min.y), Vec2f(min.x, max.y)}; + brackets.push_back(left); + + std::array right{Vec2f(max.x, max.y), Vec2f(max.x, min.y)}; + brackets.push_back(right); } void MoleculeLayout::_updateDataSGroups() @@ -402,7 +398,7 @@ Metalayout::LayoutItem& MoleculeLayout::_pushMol(Metalayout::LayoutLine& line, B item.type = 0; item.fragment = true; item.id = _map.size(); - _map.push(&mol); + _map.push_back(&mol); Metalayout::getBoundRect(item.min, item.max, mol); item.scaledSize.diff(item.max, item.min); return item; diff --git a/core/indigo-core/layout/src/molecule_layout_graph_assign.cpp b/core/indigo-core/layout/src/molecule_layout_graph_assign.cpp index d21989bdfe..edb397d636 100644 --- a/core/indigo-core/layout/src/molecule_layout_graph_assign.cpp +++ b/core/indigo-core/layout/src/molecule_layout_graph_assign.cpp @@ -559,7 +559,7 @@ void MoleculeLayoutGraph::_buildOutline(void) else if (_outline->size() > 0) break; - _outline->push(pos_i); + _outline->push_back(pos_i); max_angle = 0.f; @@ -620,7 +620,7 @@ void MoleculeLayoutGraph::_buildOutline(void) if (min_dist < 10000.f) { if (min_dist > EPSILON) - _outline->push(v); + _outline->push_back(v); const Edge& edge = getEdge(int_edge); const Vec2f& cur_v3 = getPos(edge.beg); diff --git a/core/indigo-core/layout/src/molecule_layout_graph_assign_smart.cpp b/core/indigo-core/layout/src/molecule_layout_graph_assign_smart.cpp index a22afc03cb..9fae362ac6 100644 --- a/core/indigo-core/layout/src/molecule_layout_graph_assign_smart.cpp +++ b/core/indigo-core/layout/src/molecule_layout_graph_assign_smart.cpp @@ -176,7 +176,7 @@ void MoleculeLayoutGraphSmart::_get_toches_to_component(Cycle& cycle, int compon return; QS_DEF(Array, touch_to_current_component); touch_to_current_component.clear_resize(cycle.vertexCount()); - touch_to_current_component.zerofill(); + touch_to_current_component.fill(false); for (int i = 0; i < cycle.vertexCount(); i++) { const Vertex& vert = getVertex(cycle.getVertex(i)); @@ -208,8 +208,7 @@ void MoleculeLayoutGraphSmart::_get_toches_to_component(Cycle& cycle, int compon while (!touch_to_current_component[finish]) finish = (finish + 1) % cycle.vertexCount(); - interval_list.push(); - interval_list.top().init(start, finish); + interval_list.emplace_back(start, finish); start = finish; while (_layout_component_number[cycle.getEdge(start)] == component_number) @@ -235,7 +234,7 @@ void MoleculeLayoutGraphSmart::_search_path(int start, int finish, Array& p { QS_DEF(Array, visited); visited.clear_resize(vertexEnd()); - visited.zerofill(); + visited.fill(false); visited[start] = true; QS_DEF(Array, vertices_list); @@ -702,7 +701,7 @@ void MoleculeLayoutGraphSmart::_assignEveryCycle(const Cycle& cycle) QS_DEF(Array, _is_layout_component_incoming); _is_layout_component_incoming.clear_resize(_layout_component_count); - _is_layout_component_incoming.zerofill(); + _is_layout_component_incoming.fill(false); for (int i = 0; i < size; i++) _is_layout_component_incoming[_layout_component_number[cycle.getEdge(i)]] = true; @@ -904,7 +903,7 @@ void MoleculeLayoutGraphSmart::_assignEveryCycle(const Cycle& cycle) QS_DEF(Array, need_to_insert); need_to_insert.clear_resize(size); - need_to_insert.zerofill(); + need_to_insert.fill(false); for (int i = 0; i < size; i++) need_to_insert[i] = _layout_vertices[cycle.getVertex(i)].type != ELEMENT_NOT_DRAWN; @@ -926,10 +925,10 @@ void MoleculeLayoutGraphSmart::_assignEveryCycle(const Cycle& cycle) QS_DEF(Array, takenVertex); takenVertex.clear_resize(vertexCount()); - takenVertex.zerofill(); + takenVertex.fill(false); takenVertex[cycle.getVertex(index)] = true; - _is_component_touch.zerofill(); + _is_component_touch.fill(false); for (int i = 0; i < insideVertex.size(); i++) for (int j = getVertex(insideVertex[i]).neiBegin(); j != getVertex(insideVertex[i]).neiEnd(); j = getVertex(insideVertex[i]).neiNext(j)) @@ -1365,8 +1364,8 @@ void MoleculeLayoutGraphSmart::_update_touching_segments(Array& p if (interseced) { - pairs.push(local_pair_ii(i, j)); - pairs.push(local_pair_ii(j, i)); + pairs.emplace_back(i, j); + pairs.emplace_back(j, i); } } } @@ -1409,7 +1408,7 @@ void MoleculeLayoutGraphSmart::_segment_smoothing_prepearing(const Cycle& cycle, QS_DEF(Array, layout_comp_touch); layout_comp_touch.clear_resize(_layout_component_count); - layout_comp_touch.zerofill(); + layout_comp_touch.fill(false); for (int i = 0; i < cycle_size; i++) { @@ -1437,7 +1436,7 @@ void MoleculeLayoutGraphSmart::_segment_smoothing_prepearing(const Cycle& cycle, { // search of vertices touch to i-th layout component - touch_to_current_component.zerofill(); + touch_to_current_component.fill(false); for (int j = 0; j < cycle_size; j++) { const Vertex& vert = getVertex(cycle.getVertex(j)); diff --git a/core/indigo-core/layout/src/molecule_layout_graph_attach.cpp b/core/indigo-core/layout/src/molecule_layout_graph_attach.cpp index ca70752498..ca0231cb2b 100644 --- a/core/indigo-core/layout/src/molecule_layout_graph_attach.cpp +++ b/core/indigo-core/layout/src/molecule_layout_graph_attach.cpp @@ -849,7 +849,7 @@ void MoleculeLayoutGraph::_calculatePositionsOneNotDrawn(Array& positions v1.y += 0.001f; p0.diff(v1, v2); } - angles.push(p0.tiltAngle2()); + angles.push_back(p0.tiltAngle2()); } // sort diff --git a/core/indigo-core/layout/src/molecule_layout_graph_cycle.cpp b/core/indigo-core/layout/src/molecule_layout_graph_cycle.cpp index 1d49baffff..bd79eca6f8 100644 --- a/core/indigo-core/layout/src/molecule_layout_graph_cycle.cpp +++ b/core/indigo-core/layout/src/molecule_layout_graph_cycle.cpp @@ -26,7 +26,6 @@ MoleculeLayoutGraph::Cycle::Cycle() : CP_INIT, TL_CP_GET(_vertices), TL_CP_GET(_ { _vertices.clear(); _edges.clear(); - _attached_weight.clear(); _max_idx = 0; _morgan_code_calculated = false; } diff --git a/core/indigo-core/layout/src/molecule_layout_graph_geom.cpp b/core/indigo-core/layout/src/molecule_layout_graph_geom.cpp index e8238ffc83..57495d9d01 100644 --- a/core/indigo-core/layout/src/molecule_layout_graph_geom.cpp +++ b/core/indigo-core/layout/src/molecule_layout_graph_geom.cpp @@ -413,7 +413,7 @@ float MoleculeLayoutGraphSimple::calculateAngle(int v, int& v1, int& v2) const { edges.push(i); p0.diff(getPos(vert.neiVertex(i)), getPos(v)); - angles.push(p0.tiltAngle2()); + angles.push_back(p0.tiltAngle2()); } // Sort @@ -673,7 +673,7 @@ float MoleculeLayoutGraphSmart::calculateAngle(int v, int& v1, int& v2) const { edges.push(i); p0.diff(getPos(vert.neiVertex(i)), getPos(v)); - angles.push(p0.tiltAngle2()); + angles.push_back(p0.tiltAngle2()); } // Sort diff --git a/core/indigo-core/layout/src/molecule_layout_macrocycle_lattice.cpp b/core/indigo-core/layout/src/molecule_layout_macrocycle_lattice.cpp index 2eccfd7d34..3e31de65af 100644 --- a/core/indigo-core/layout/src/molecule_layout_macrocycle_lattice.cpp +++ b/core/indigo-core/layout/src/molecule_layout_macrocycle_lattice.cpp @@ -133,10 +133,7 @@ void MoleculeLayoutMacrocyclesLattice::doLayout() for (int y = lat.getFirstValidY(x); lat.isIncreaseForValidY(y); lat.switchNextY(y)) { if (lat.getCell(x, y) < SHORT_INFINITY) - { - answer_point point(rot, p, x, y); - points.push(point); - } + points.emplace_back(rot, p, x, y); } } } @@ -1332,8 +1329,8 @@ void MoleculeLayoutMacrocyclesLattice::updateTouchingPoints(Array int t; for (t = cl.external_vertex_number[j], s = 0; t < cl.external_vertex_number[(j + 1) % len]; t++, s += 1.0f / cl.edge_length[j]) { - all_points.push(cl.point[j] * (1 - s) + cl.point[j] * s); - all_numbers.push(j + s); + all_points.push_back(cl.point[j] * (1 - s) + cl.point[j] * s); + all_numbers.push_back(j + s); } } @@ -1347,7 +1344,7 @@ void MoleculeLayoutMacrocyclesLattice::updateTouchingPoints(Array float distSqr = (cl.point[i] - all_points[j]).lengthSqr(); if (eps2 < distSqr && distSqr < good_distance) { - pairs.push(local_pair_id(i, all_numbers[j])); + pairs.emplace_back(i, all_numbers[j]); } } } diff --git a/core/indigo-core/layout/src/molecule_layout_macrocycles.cpp b/core/indigo-core/layout/src/molecule_layout_macrocycles.cpp index beddaaf87f..19a7e26231 100644 --- a/core/indigo-core/layout/src/molecule_layout_macrocycles.cpp +++ b/core/indigo-core/layout/src/molecule_layout_macrocycles.cpp @@ -69,7 +69,7 @@ MoleculeLayoutMacrocycles::MoleculeLayoutMacrocycles(int size) _edge_stereo.zerofill(); _vertex_drawn.clear_resize(size); - _vertex_drawn.zerofill(); + _vertex_drawn.fill(false); _positions.clear_resize(size); @@ -1269,8 +1269,8 @@ float MoleculeLayoutMacrocycles::depictionCircle() QS_DEF(Array, only_up); up.clear_resize(length + 1); only_up.clear_resize(length + 1); - up.zerofill(); - only_up.zerofill(); + up.fill(false); + only_up.fill(false); for (int i = 0; i < length; i++) if (_edge_stereo[i] == MoleculeCisTrans::CIS && _edge_stereo[(i + length - 1) % length] == MoleculeCisTrans::CIS) diff --git a/core/indigo-core/layout/src/refinement_state.cpp b/core/indigo-core/layout/src/refinement_state.cpp index 79863c1bed..d06e079fd3 100644 --- a/core/indigo-core/layout/src/refinement_state.cpp +++ b/core/indigo-core/layout/src/refinement_state.cpp @@ -247,7 +247,7 @@ float RefinementState::calc_best_angle() QS_DEF(Array, take); convex_hull.resize(_graph.vertexEnd() + 1); take.resize(_graph.vertexEnd()); - take.zerofill(); + take.fill(false); int index = 0; diff --git a/core/indigo-core/molecule/molecule_json_loader.h b/core/indigo-core/molecule/molecule_json_loader.h index 55463f918d..1de5b05d70 100644 --- a/core/indigo-core/molecule/molecule_json_loader.h +++ b/core/indigo-core/molecule/molecule_json_loader.h @@ -26,7 +26,6 @@ #include "base_c/defs.h" #include "base_cpp/exception.h" -#include "base_cpp/non_copyable.h" #include "molecule/molecule_stereocenter_options.h" #ifdef _WIN32 @@ -48,7 +47,7 @@ namespace indigo * Loader for JSON format */ - class DLLEXPORT MoleculeJsonLoader : public NonCopyable + class DLLEXPORT MoleculeJsonLoader { using RGroupDescriptionList = std::list>>; diff --git a/core/indigo-core/molecule/molecule_morgan_fingerprint_builder.h b/core/indigo-core/molecule/molecule_morgan_fingerprint_builder.h index ef084d9a0a..70f8e15d36 100644 --- a/core/indigo-core/molecule/molecule_morgan_fingerprint_builder.h +++ b/core/indigo-core/molecule/molecule_morgan_fingerprint_builder.h @@ -29,7 +29,7 @@ namespace indigo { - class DLLEXPORT MoleculeMorganFingerprintBuilder : public NonCopyable + class DLLEXPORT MoleculeMorganFingerprintBuilder { public: explicit MoleculeMorganFingerprintBuilder(BaseMolecule& mol); diff --git a/core/indigo-core/molecule/molecule_name_parser.h b/core/indigo-core/molecule/molecule_name_parser.h index d0ef85d593..cbca3be1bc 100644 --- a/core/indigo-core/molecule/molecule_name_parser.h +++ b/core/indigo-core/molecule/molecule_name_parser.h @@ -39,7 +39,6 @@ #include "molecule/token_types.inc" #include "molecule/trivial.inc" -#include "base_cpp/non_copyable.h" #include "base_cpp/obj_array.h" #include "base_cpp/scanner.h" #include "base_cpp/tree.h" @@ -197,7 +196,7 @@ namespace indigo /* A dictionary for managing various global symbol tables */ - class DictionaryManager : public NonCopyable + class DictionaryManager { public: DictionaryManager(); @@ -228,7 +227,7 @@ namespace indigo A product of parsing process Keeps dictionaries of lexemes and tokens */ - class Parse : public NonCopyable + class Parse { public: inline explicit Parse(const std::string& in, const MoleculeNameParser& mnp) : input(in), mnp(mnp){}; @@ -288,7 +287,7 @@ namespace indigo respective order before base node. Later, depth-first traversal is used to create Molecule objects */ - class FragmentNode : NonCopyable + class FragmentNode { public: FragmentNode() = default; @@ -451,7 +450,7 @@ namespace indigo Can have multiple roots as a whitespace ' ' in the input denotes separate structures that must be handled separately */ - class FragmentBuildTree : public NonCopyable + class FragmentBuildTree { public: FragmentBuildTree(); @@ -469,7 +468,7 @@ namespace indigo Constructs a build tree from a Parse object Builds all trees in one pass, consequently reading the lexemes stream */ - class TreeBuilder : public NonCopyable + class TreeBuilder { public: inline TreeBuilder(const Parse& input) : _parse{&input} @@ -550,7 +549,7 @@ namespace indigo typedef std::map Elements; struct SmilesRoot; - struct SmilesNode : public NonCopyable + struct SmilesNode { std::vector roots; SmilesRoot* parent = nullptr; @@ -586,7 +585,7 @@ namespace indigo } }; - struct SmilesRoot : public NonCopyable + struct SmilesRoot { std::vector nodes; SmilesNode* parent = nullptr; @@ -617,7 +616,7 @@ namespace indigo Builds a resulting structure from a build tree Uses depth-first traversal */ - class SmilesBuilder : public NonCopyable + class SmilesBuilder { public: SmilesBuilder(const Parse& input) : _treeBuilder{input} diff --git a/core/indigo-core/molecule/molecule_rgroups.h b/core/indigo-core/molecule/molecule_rgroups.h index aca05c3c70..9fc0bdc62a 100644 --- a/core/indigo-core/molecule/molecule_rgroups.h +++ b/core/indigo-core/molecule/molecule_rgroups.h @@ -33,9 +33,12 @@ namespace indigo class BaseMolecule; - struct RGroup + struct DLLEXPORT RGroup { explicit RGroup(); + explicit RGroup(const RGroup& other); + RGroup& operator=(const RGroup& other); + ~RGroup(); void clear(); @@ -47,9 +50,6 @@ namespace indigo int if_then; int rest_h; Array occurrence; - - protected: - explicit RGroup(RGroup& other); }; class DLLEXPORT MoleculeRGroups diff --git a/core/indigo-core/molecule/molecule_rgroups_composition.h b/core/indigo-core/molecule/molecule_rgroups_composition.h index 1191570526..4bcf46a029 100644 --- a/core/indigo-core/molecule/molecule_rgroups_composition.h +++ b/core/indigo-core/molecule/molecule_rgroups_composition.h @@ -28,14 +28,14 @@ namespace indigo { - class MoleculeRGroupsComposition : NonCopyable + class MoleculeRGroupsComposition { public: explicit MoleculeRGroupsComposition(BaseMolecule& mol); ~MoleculeRGroupsComposition(){}; // State of search abstracted from chemistry details - class AttachmentIter : NonCopyable + class AttachmentIter { public: // Default constructor is used to indicate final state @@ -73,7 +73,7 @@ namespace indigo }; // Collection of search states - class Attachments : NonCopyable + class Attachments { public: Attachments(int size, const Array& limits) : _limits(limits), _end(), _size(size) diff --git a/core/indigo-core/molecule/molecule_sgroups.h b/core/indigo-core/molecule/molecule_sgroups.h index 76fd07453d..64d71421b9 100644 --- a/core/indigo-core/molecule/molecule_sgroups.h +++ b/core/indigo-core/molecule/molecule_sgroups.h @@ -23,6 +23,7 @@ #include "base_cpp/obj_pool.h" #include "base_cpp/ptr_pool.h" #include "math/algebra.h" +#include #ifdef _WIN32 #pragma warning(push) @@ -111,8 +112,8 @@ namespace indigo Array atoms; // represented with SAL in Molfile format Array bonds; // represented with SBL in Molfile format - int brk_style; // represented with SBT in Molfile format - Array brackets; // represented with SDI in Molfile format + int brk_style; // represented with SBT in Molfile format + Array> brackets; // represented with SDI in Molfile format static const char* typeToString(int sg_type); static int getType(const char* sg_type); diff --git a/core/indigo-core/molecule/molecule_tgroups.h b/core/indigo-core/molecule/molecule_tgroups.h index 0082459782..871f3a8772 100644 --- a/core/indigo-core/molecule/molecule_tgroups.h +++ b/core/indigo-core/molecule/molecule_tgroups.h @@ -45,16 +45,15 @@ namespace indigo int tgroup_id; TGroup(); + TGroup(const TGroup& other); + ~TGroup(); - void copy(TGroup& other); + void copy(const TGroup& other); void clear(); static int cmp(TGroup& tg1, TGroup& tg2, void* context); std::unique_ptr fragment; - - private: - TGroup(const TGroup&); }; class DLLEXPORT MoleculeTGroups diff --git a/core/indigo-core/molecule/smiles_loader.h b/core/indigo-core/molecule/smiles_loader.h index eca8f13073..5c65541626 100644 --- a/core/indigo-core/molecule/smiles_loader.h +++ b/core/indigo-core/molecule/smiles_loader.h @@ -81,6 +81,7 @@ namespace indigo class DLLEXPORT _AtomDesc { public: + _AtomDesc(); _AtomDesc(Pool::Elem>& neipool); ~_AtomDesc(); diff --git a/core/indigo-core/molecule/src/base_molecule.cpp b/core/indigo-core/molecule/src/base_molecule.cpp index 705976f0ac..da37e9b34c 100644 --- a/core/indigo-core/molecule/src/base_molecule.cpp +++ b/core/indigo-core/molecule/src/base_molecule.cpp @@ -175,7 +175,7 @@ void BaseMolecule::mergeSGroupsWithSubmolecule(BaseMolecule& mol, Array& ma { if (supersa.bond_connections[j].bond_idx > -1 && edge_mapping[supersa.bond_connections[j].bond_idx] > -1) { - Superatom::_BondConnection& bond = sa.bond_connections.push(); + Superatom::_BondConnection& bond = sa.bond_connections.emplace_back(); bond.bond_dir = supersa.bond_connections[j].bond_dir; bond.bond_idx = edge_mapping[supersa.bond_connections[j].bond_idx]; } diff --git a/core/indigo-core/molecule/src/cmf_loader.cpp b/core/indigo-core/molecule/src/cmf_loader.cpp index 5ef20900cb..7c50fbd5db 100644 --- a/core/indigo-core/molecule/src/cmf_loader.cpp +++ b/core/indigo-core/molecule/src/cmf_loader.cpp @@ -258,7 +258,7 @@ bool CmfLoader::_readAtom(int& code, _AtomDesc& atom, int atom_idx) if (!_getNextCode(aidx)) throw Error("expected attachment index"); - _AttachmentDesc& att = _attachments.push(); + _AttachmentDesc& att = _attachments.emplace_back(); att.atom = atom_idx; att.index = aidx; @@ -496,7 +496,7 @@ void CmfLoader::loadMolecule(Molecule& mol) if (!first_atom) { - bond = &_bonds.push(); + bond = &_bonds.emplace_back(); bond->beg = atom_stack.top(); } @@ -521,7 +521,7 @@ void CmfLoader::loadMolecule(Molecule& mol) } } - _AtomDesc& atom = _atoms.push(); + _AtomDesc& atom = _atoms.emplace_back(); if (!first_atom) atom_stack.pop(); diff --git a/core/indigo-core/molecule/src/cml_loader.cpp b/core/indigo-core/molecule/src/cml_loader.cpp index 000c562efe..edc11b2961 100644 --- a/core/indigo-core/molecule/src/cml_loader.cpp +++ b/core/indigo-core/molecule/src/cml_loader.cpp @@ -16,11 +16,10 @@ * limitations under the License. ***************************************************************************/ -#include "molecule/cml_loader.h" - #include #include "base_cpp/scanner.h" +#include "molecule/cml_loader.h" #include "molecule/elements.h" #include "molecule/molecule.h" #include "molecule/molecule_scaffold_detection.h" @@ -1312,6 +1311,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_map bracket; Vec2f* pbrackets; XMLElement* pPoint; for (pPoint = brackets->FirstChildElement(); pPoint; pPoint = pPoint->NextSiblingElement()) @@ -1320,7 +1320,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_mapbrackets.push(); + pbrackets = &dsg->brackets.push_back(bracket)[0]; const char* point_x = pPoint->Attribute("x"); const char* point_y = pPoint->Attribute("y"); @@ -1469,6 +1469,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_map bracket; XMLElement* pPoint; for (pPoint = brackets->FirstChildElement(); pPoint; pPoint = pPoint->NextSiblingElement()) { @@ -1476,7 +1477,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_mapbrackets.push(); + pbrackets = &gen->brackets.push_back(bracket)[0]; float x = 0, y = 0; const char* point_x = pPoint->Attribute("x"); @@ -1547,6 +1548,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_map bracket; XMLElement* pPoint; for (pPoint = brackets->FirstChildElement(); pPoint; pPoint = pPoint->NextSiblingElement()) { @@ -1554,7 +1556,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_mapbrackets.push(); + pbrackets = &sru->brackets.push_back(bracket)[0]; float x = 0, y = 0; const char* point_x = pPoint->Attribute("x"); @@ -1656,6 +1658,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_map bracket; XMLElement* pPoint; for (pPoint = brackets->FirstChildElement(); pPoint; pPoint = pPoint->NextSiblingElement()) { @@ -1663,7 +1666,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_mapbrackets.push(); + pbrackets = &mul->brackets.push_back(bracket)[0]; float x = 0, y = 0; const char* point_x = pPoint->Attribute("x"); @@ -1741,6 +1744,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_map bracket; XMLElement* pPoint; for (pPoint = brackets->FirstChildElement(); pPoint; pPoint = pPoint->NextSiblingElement()) { @@ -1748,7 +1752,7 @@ void CmlLoader::_loadSGroupElement(XMLElement* elem, std::unordered_mapbrackets.push(); + pbrackets = &sup->brackets.push_back(bracket)[0]; const char* point_x = pPoint->Attribute("x"); const char* point_y = pPoint->Attribute("y"); diff --git a/core/indigo-core/molecule/src/inchi_wrapper.cpp b/core/indigo-core/molecule/src/inchi_wrapper.cpp index 5da196f263..74288fe237 100644 --- a/core/indigo-core/molecule/src/inchi_wrapper.cpp +++ b/core/indigo-core/molecule/src/inchi_wrapper.cpp @@ -502,7 +502,7 @@ void InchiWrapper::generateInchiInput(Molecule& mol, inchi_Input& input, Array= 0) { diff --git a/core/indigo-core/molecule/src/molecule_cdx_loader.cpp b/core/indigo-core/molecule/src/molecule_cdx_loader.cpp index 4bbab5479e..2ad635818d 100644 --- a/core/indigo-core/molecule/src/molecule_cdx_loader.cpp +++ b/core/indigo-core/molecule/src/molecule_cdx_loader.cpp @@ -310,7 +310,7 @@ void MoleculeCdxLoader::_readNode(UINT32 node_id) int level = 1; - _NodeDesc& node = _nodes.push(); + _NodeDesc& node = _nodes.emplace_back(); memset(&node, 0, sizeof(_NodeDesc)); node.id = node_id; node.type = kCDXNodeType_Element; @@ -461,7 +461,7 @@ void MoleculeCdxLoader::_getBondOrdering(int size, Array<_ExtConnection>& connec for (int i = 0; i < nbonds; i++) { - _ExtConnection& conn = connections.push(); + _ExtConnection& conn = connections.emplace_back(); conn.bond_id = _scanner->readBinaryDword(); conn.point_id = 0; conn.atom_id = 0; @@ -492,7 +492,7 @@ void MoleculeCdxLoader::_readBond(UINT32 bond_id) int level = 1; - _BondDesc& bond = _bonds.push(); + _BondDesc& bond = _bonds.emplace_back(); memset(&bond, 0, sizeof(_BondDesc)); bond.id = bond_id; bond.type = BOND_SINGLE; diff --git a/core/indigo-core/molecule/src/molecule_cdxml_loader.cpp b/core/indigo-core/molecule/src/molecule_cdxml_loader.cpp index 05a687d101..c3261a7fc2 100644 --- a/core/indigo-core/molecule/src/molecule_cdxml_loader.cpp +++ b/core/indigo-core/molecule/src/molecule_cdxml_loader.cpp @@ -315,12 +315,11 @@ void MoleculeCdxmlLoader::_addBracket(BaseMolecule& mol, const CdxmlBracket& bra } // add brackets - Vec2f* p = sgroup.brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); - p = sgroup.brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); + std::array v; + v[0].set(0, 0); + v[1].set(0, 0); + sgroup.brackets.push_back(v); + sgroup.brackets.push_back(v); // sgroup.brk_style switch (bracket.usage) { diff --git a/core/indigo-core/molecule/src/molecule_cip_calculator.cpp b/core/indigo-core/molecule/src/molecule_cip_calculator.cpp index 567ebeff72..7131055e96 100644 --- a/core/indigo-core/molecule/src/molecule_cip_calculator.cpp +++ b/core/indigo-core/molecule/src/molecule_cip_calculator.cpp @@ -796,9 +796,7 @@ bool MoleculeCIPCalculator::_checkLigandsEquivalence(Array& ligands, Array< if (_cip_rules_cmp(ligands[k], ligands[l], &context) == 0) { - auto& equiv_pair = equiv_ligands.push(); - equiv_pair[0] = ligands[k]; - equiv_pair[1] = ligands[l]; + equiv_ligands.push_back({ligands[k], ligands[l]}); neq++; } else if (context.use_rule_5) diff --git a/core/indigo-core/molecule/src/molecule_cis_trans.cpp b/core/indigo-core/molecule/src/molecule_cis_trans.cpp index 4d673afcb6..6085bde3c5 100644 --- a/core/indigo-core/molecule/src/molecule_cis_trans.cpp +++ b/core/indigo-core/molecule/src/molecule_cis_trans.cpp @@ -357,7 +357,7 @@ bool MoleculeCisTrans::exists() const void MoleculeCisTrans::registerBond(int idx) { while (_bonds.size() <= idx) - _bonds.push().clear(); + _bonds.emplace_back().clear(); _bonds[idx].clear(); } @@ -547,7 +547,7 @@ bool MoleculeCisTrans::isIgnored(int bond_idx) const void MoleculeCisTrans::ignore(int bond_idx) { while (bond_idx >= _bonds.size()) - _bonds.push().clear(); + _bonds.emplace_back().clear(); _bonds[bond_idx].parity = 0; _bonds[bond_idx].ignored = 1; } @@ -555,7 +555,7 @@ void MoleculeCisTrans::ignore(int bond_idx) void MoleculeCisTrans::setParity(int bond_idx, int parity) { while (_bonds.size() <= bond_idx) - _bonds.push().clear(); + _bonds.emplace_back().clear(); _bonds[bond_idx].parity = parity; } @@ -736,7 +736,7 @@ void MoleculeCisTrans::buildOnSubmolecule(BaseMolecule& baseMolecule, BaseMolecu while (_bonds.size() < baseMolecule.edgeEnd()) { - _Bond& bond = _bonds.push(); + _Bond& bond = _bonds.emplace_back(); memset(&bond, 0, sizeof(_Bond)); } diff --git a/core/indigo-core/molecule/src/molecule_gross_formula.cpp b/core/indigo-core/molecule/src/molecule_gross_formula.cpp index d1a6221117..0289303277 100644 --- a/core/indigo-core/molecule/src/molecule_gross_formula.cpp +++ b/core/indigo-core/molecule/src/molecule_gross_formula.cpp @@ -281,8 +281,7 @@ void MoleculeGrossFormula::_toString(const Array& gross, ArrayOutput& outpu for (i = 1; i < ELEM_MAX; i++) { - _ElemCounter& ec = counters.push(); - + _ElemCounter& ec = counters.emplace_back(); ec.elem = i; ec.counter = gross[i]; } @@ -328,7 +327,7 @@ void MoleculeGrossFormula::_toString(const RedBlackMap& isotopes, Arra if (isotopes.key(i) == ELEM_RSITE) continue; - _ElemCounter& ec = counters.push(); + _ElemCounter& ec = counters.emplace_back(); number = isotopes.key(i) & 0xFF; isotope = isotopes.key(i) >> 8; diff --git a/core/indigo-core/molecule/src/molecule_inchi_layers.cpp b/core/indigo-core/molecule/src/molecule_inchi_layers.cpp index 62e5ad8423..d45b4d37e6 100644 --- a/core/indigo-core/molecule/src/molecule_inchi_layers.cpp +++ b/core/indigo-core/molecule/src/molecule_inchi_layers.cpp @@ -28,6 +28,7 @@ using namespace indigo; using namespace indigo::MoleculeInChILayers; +using intpair = std::array; IMPL_ERROR(AbstractLayer, "InChI layer"); @@ -570,7 +571,7 @@ void CisTransStereochemistryLayer::print(Array& result) ArrayOutput output(result); Molecule& mol = _getMolecule(); - QS_DEF(Array, dbl); + QS_DEF(Array, dbl); dbl.clear_resize(mol.vertexEnd()); dbl.fffill(); @@ -585,7 +586,7 @@ void CisTransStereochemistryLayer::print(Array& result) int max_vertex = std::max(e.beg, e.end); int min_vertex = std::min(e.beg, e.end); - int(&cp)[2] = dbl[max_vertex]; + auto& cp = dbl[max_vertex]; cp[0] = min_vertex; cp[1] = e_idx; @@ -627,8 +628,8 @@ int CisTransStereochemistryLayer::compareMappings(const MoleculeInChIUtils::Mapp // Compare cis-trans for double bonds (>X=Y<) and cumulene (>W=X=Y=Z<). // TODO: handle cumulene - QS_DEF(Array, dbl1); - QS_DEF(Array, dbl2); + QS_DEF(Array, dbl1); + QS_DEF(Array, dbl2); dbl1.clear_resize(m1.mapping.size()); dbl1.zerofill(); @@ -658,8 +659,8 @@ int CisTransStereochemistryLayer::compareMappings(const MoleculeInChIUtils::Mapp else parity2 = 2; - int(&cp1)[2] = dbl1[m1.inv_mapping[max_vertex]]; - int(&cp2)[2] = dbl2[m1.inv_mapping[max_vertex]]; + auto& cp1 = dbl1[m1.inv_mapping[max_vertex]]; + auto& cp2 = dbl2[m1.inv_mapping[max_vertex]]; cp1[0] = m1.inv_mapping[min_vertex]; cp1[1] = parity1; @@ -767,8 +768,8 @@ int TetrahedralStereochemistryLayer::compareMappings(const MoleculeInChIUtils::M { Molecule& mol = _getMolecule(); - QS_DEF(Array, dbl1); - QS_DEF(Array, dbl2); + QS_DEF(Array, dbl1); + QS_DEF(Array, dbl2); dbl1.clear_resize(m1.mapping.size()); dbl1.zerofill(); diff --git a/core/indigo-core/molecule/src/molecule_ionize.cpp b/core/indigo-core/molecule/src/molecule_ionize.cpp index fbc3913355..2929a2229c 100644 --- a/core/indigo-core/molecule/src/molecule_ionize.cpp +++ b/core/indigo-core/molecule/src/molecule_ionize.cpp @@ -135,7 +135,7 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* while (!scan_apka.isEOF()) { float val = scan_apka.readFloat(); - a_pka.push(val); + a_pka.push_back(val); } if (a_sites.size() > 1) @@ -162,7 +162,7 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* acid_pka_cids.insert(fp.ptr()); a_count++; } - acid_pkas.at(fp.ptr()).push(val); + acid_pkas.at(fp.ptr()).push_back(val); acid_pka_cids.at(fp.ptr()).push(cid); } } @@ -186,7 +186,7 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* while (!scan_bpka.isEOF()) { float val = scan_bpka.readFloat(); - b_pka.push(val); + b_pka.push_back(val); } if (b_sites.size() > 1) @@ -213,7 +213,7 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* basic_pka_cids.insert(fp.ptr()); b_count++; } - basic_pkas.at(fp.ptr()).push(val); + basic_pkas.at(fp.ptr()).push_back(val); basic_pka_cids.at(fp.ptr()).push(cid); } } @@ -252,8 +252,8 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* if (_model.adv_a_pkas.find(fp)) _model.adv_a_pkas.remove(fp); _model.adv_a_pkas.insert(fp); - _model.adv_a_pkas.at(fp).push(pka_sum / pkas.size()); - _model.adv_a_pkas.at(fp).push(pka_dev); + _model.adv_a_pkas.at(fp).push_back(pka_sum / pkas.size()); + _model.adv_a_pkas.at(fp).push_back(pka_dev); if (pka_dev > threshold) model_ready = false; @@ -288,8 +288,8 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* if (_model.adv_b_pkas.find(fp)) _model.adv_b_pkas.remove(fp); _model.adv_b_pkas.insert(fp); - _model.adv_b_pkas.at(fp).push(pka_sum / pkas.size()); - _model.adv_b_pkas.at(fp).push(pka_dev); + _model.adv_b_pkas.at(fp).push_back(pka_sum / pkas.size()); + _model.adv_b_pkas.at(fp).push_back(pka_dev); if (pka_dev > threshold) model_ready = false; @@ -309,7 +309,7 @@ int MoleculePkaModel::buildPkaModel(int max_level, float threshold, const char* else { level++; - _model.max_deviations.push(max_deviation); + _model.max_deviations.push_back(max_deviation); } } } @@ -407,7 +407,7 @@ void MoleculePkaModel::_loadSimplePkaModel() SmilesLoader loader(scanner); QueryMolecule& acid = _model.acids.push(); loader.loadSMARTS(acid); - _model.a_pkas.push(simple_pka_model[i].pka); + _model.a_pkas.push_back(simple_pka_model[i].pka); } for (auto i = 0; i < NELEM(simple_pka_model); i++) @@ -416,7 +416,7 @@ void MoleculePkaModel::_loadSimplePkaModel() SmilesLoader loader(scanner); QueryMolecule& basic = _model.basics.push(); loader.loadSMARTS(basic); - _model.b_pkas.push(simple_pka_model[i].pka); + _model.b_pkas.push_back(simple_pka_model[i].pka); } _model.simple_model_ready = true; @@ -825,8 +825,8 @@ namespace // data of internal purpose adv_model.remove(from->a_fp); adv_model.insert(from->a_fp); - adv_model.at(from->a_fp).push(from->pka); - adv_model.at(from->a_fp).push(from->deviation); + adv_model.at(from->a_fp).push_back(from->pka); + adv_model.at(from->a_fp).push_back(from->deviation); } } } // namespace @@ -874,7 +874,7 @@ void MoleculePkaModel::_estimate_pKa_Simple(Molecule& mol, const IonizeOptions& if (mapping[j] > -1) { acid_sites.push(mapping[j]); - acid_pkas.push(_model.a_pkas[i]); + acid_pkas.push_back(_model.a_pkas[i]); ignore_atoms.push(mapping[j]); } } @@ -898,7 +898,7 @@ void MoleculePkaModel::_estimate_pKa_Simple(Molecule& mol, const IonizeOptions& if (mapping[j] > -1) { basic_sites.push(mapping[j]); - basic_pkas.push(_model.b_pkas[i]); + basic_pkas.push_back(_model.b_pkas[i]); ignore_atoms.push(mapping[j]); } } @@ -927,7 +927,7 @@ void MoleculePkaModel::_estimate_pKa_Advanced(Molecule& mol, const IonizeOptions { float a_pka = getAcidPkaValue(mol, i, level, min_level); acid_sites.push(i); - acid_pkas.push(a_pka); + acid_pkas.push_back(a_pka); // printf("Acid site: atom index = %d, pKa = %f\n", can_order[i], a_pka); } @@ -935,7 +935,7 @@ void MoleculePkaModel::_estimate_pKa_Advanced(Molecule& mol, const IonizeOptions { float b_pka = getBasicPkaValue(mol, i, level, min_level); basic_sites.push(i); - basic_pkas.push(b_pka); + basic_pkas.push_back(b_pka); // printf("Basic site: atom index = %d, pKa = %f\n", can_order[i], b_pka); } } diff --git a/core/indigo-core/molecule/src/molecule_json_loader.cpp b/core/indigo-core/molecule/src/molecule_json_loader.cpp index 694fe55fea..c7b9200afe 100644 --- a/core/indigo-core/molecule/src/molecule_json_loader.cpp +++ b/core/indigo-core/molecule/src/molecule_json_loader.cpp @@ -762,13 +762,11 @@ void MoleculeJsonLoader::parseSGroups(const rapidjson::Value& sgroups, BaseMolec } // add brackets - Vec2f* p = sgroup.brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); - p = sgroup.brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); - + std::array v; + v[0].set(0, 0); + v[1].set(0, 0); + sgroup.brackets.push_back(v); + sgroup.brackets.push_back(v); // add specific parameters switch (sg_type) { diff --git a/core/indigo-core/molecule/src/molecule_layered_molecules.cpp b/core/indigo-core/molecule/src/molecule_layered_molecules.cpp index 3e42e8fdd3..de4c2c1118 100644 --- a/core/indigo-core/molecule/src/molecule_layered_molecules.cpp +++ b/core/indigo-core/molecule/src/molecule_layered_molecules.cpp @@ -62,7 +62,7 @@ LayeredMolecules::LayeredMolecules(BaseMolecule& molecule) : _layersAromatized(0 bool stub; node = _trie.add(node, _proto.getBondOrder(i), stub); } - _hashs.push(node); + _hashs.push_back(node); } LayeredMolecules::~LayeredMolecules() @@ -188,7 +188,7 @@ bool LayeredMolecules::addLayersWithInvertedPath(const Dbitset& mask, const Arra _mobilePositionsOccupied[i].set(newTautomerIndex); } - _hashs.push(node); + _hashs.push_back(node); ++layers; maskCopy.reset(prototypeIndex); _mobilePositionsOccupied[forward ? beg : end].reset(newTautomerIndex); diff --git a/core/indigo-core/molecule/src/molecule_mass.cpp b/core/indigo-core/molecule/src/molecule_mass.cpp index ef07a2e9de..f371833e8e 100644 --- a/core/indigo-core/molecule/src/molecule_mass.cpp +++ b/core/indigo-core/molecule/src/molecule_mass.cpp @@ -395,7 +395,7 @@ void MoleculeMass::massComposition(Molecule& mol, Array& str) for (i = ELEM_MIN; i < ELEM_MAX; i++) { - _ElemCounter& ec = counters.push(); + _ElemCounter& ec = counters.emplace_back(); ec.elem = i; ec.weight = (relativeMass[i] / totalWeight) * 100; diff --git a/core/indigo-core/molecule/src/molecule_morgan_fingerprint_builder.cpp b/core/indigo-core/molecule/src/molecule_morgan_fingerprint_builder.cpp index 421753c9a0..a1fa03aae2 100644 --- a/core/indigo-core/molecule/src/molecule_morgan_fingerprint_builder.cpp +++ b/core/indigo-core/molecule/src/molecule_morgan_fingerprint_builder.cpp @@ -38,7 +38,7 @@ void MoleculeMorganFingerprintBuilder::calculateDescriptorsECFP(int fp_depth, Ar for (auto& feature : features) { - res.push(feature.hash); + res.push_back(feature.hash); } } @@ -51,7 +51,7 @@ void MoleculeMorganFingerprintBuilder::calculateDescriptorsFCFP(int fp_depth, Ar for (auto& feature : features) { - res.push(feature.hash); + res.push_back(feature.hash); } } diff --git a/core/indigo-core/molecule/src/molecule_pi_systems_matcher.cpp b/core/indigo-core/molecule/src/molecule_pi_systems_matcher.cpp index d8084c13fb..8f6568fd15 100644 --- a/core/indigo-core/molecule/src/molecule_pi_systems_matcher.cpp +++ b/core/indigo-core/molecule/src/molecule_pi_systems_matcher.cpp @@ -407,7 +407,7 @@ void MoleculePiSystemsMatcher::_findPiSystemLocalization(int pi_system_index) } // Add localization - _Pi_System::Localizations& loc = pi_system.localizations.push(); + _Pi_System::Localizations& loc = pi_system.localizations.emplace_back(); loc.double_bonds = double_bonds; loc.primary_lp = zero_lp; loc.seconary_lp = other_lp; diff --git a/core/indigo-core/molecule/src/molecule_rgroups.cpp b/core/indigo-core/molecule/src/molecule_rgroups.cpp index fdf73cb1b7..6f63872346 100644 --- a/core/indigo-core/molecule/src/molecule_rgroups.cpp +++ b/core/indigo-core/molecule/src/molecule_rgroups.cpp @@ -26,6 +26,17 @@ RGroup::RGroup() : if_then(0), rest_h(0) { } +RGroup::RGroup(const RGroup& other) +{ + copy(const_cast(other)); +} + +RGroup& RGroup::operator=(const RGroup& other) +{ + copy(const_cast(other)); + return *this; +} + RGroup::~RGroup() { } diff --git a/core/indigo-core/molecule/src/molecule_tautomer_superstructure.cpp b/core/indigo-core/molecule/src/molecule_tautomer_superstructure.cpp index cfa51d6aaf..75629d9020 100644 --- a/core/indigo-core/molecule/src/molecule_tautomer_superstructure.cpp +++ b/core/indigo-core/molecule/src/molecule_tautomer_superstructure.cpp @@ -90,7 +90,7 @@ TautomerSuperStructure::TautomerSuperStructure(Molecule& mol) } _isBondAttachedArray.resize(edgeEnd()); - _isBondAttachedArray.zerofill(); + _isBondAttachedArray.fill(false); for (int i = 0; i < attachedBonds.size(); i++) _isBondAttachedArray[attachedBonds[i]] = true; diff --git a/core/indigo-core/molecule/src/molecule_tgroups.cpp b/core/indigo-core/molecule/src/molecule_tgroups.cpp index 2c4f43022b..e473d83ea6 100644 --- a/core/indigo-core/molecule/src/molecule_tgroups.cpp +++ b/core/indigo-core/molecule/src/molecule_tgroups.cpp @@ -24,6 +24,11 @@ using namespace indigo; +TGroup::TGroup(const TGroup& other) +{ + copy(other); +} + TGroup::TGroup() { } @@ -101,7 +106,7 @@ int TGroup::cmp(TGroup& tg1, TGroup& tg2, void* context) return -1; } -void TGroup::copy(TGroup& other) +void TGroup::copy(const TGroup& other) { tgroup_class.copy(other.tgroup_class); tgroup_name.copy(other.tgroup_name); diff --git a/core/indigo-core/molecule/src/molfile_loader.cpp b/core/indigo-core/molecule/src/molfile_loader.cpp index 467387b600..6cc8516ba8 100644 --- a/core/indigo-core/molecule/src/molfile_loader.cpp +++ b/core/indigo-core/molecule/src/molfile_loader.cpp @@ -1082,8 +1082,7 @@ void MolfileLoader::_readCtab2000() { if (n == 4) // should always be 4 { - Vec2f* brackets = sgroup->brackets.push(); - + std::array brackets; _scanner.skipSpace(); brackets[0].x = _scanner.readFloat(); _scanner.skipSpace(); @@ -1092,6 +1091,7 @@ void MolfileLoader::_readCtab2000() brackets[1].x = _scanner.readFloat(); _scanner.skipSpace(); brackets[1].y = _scanner.readFloat(); + sgroup->brackets.push_back(brackets); } } else @@ -1298,7 +1298,7 @@ void MolfileLoader::_readCtab2000() if (_sgroup_types[sgroup_idx] == SGroup::SG_TYPE_SUP) { Superatom& sup = (Superatom&)_bmol->sgroups.getSGroup(_sgroup_mapping[sgroup_idx]); - Superatom::_BondConnection& bond = sup.bond_connections.push(); + Superatom::_BondConnection& bond = sup.bond_connections.emplace_back(); _scanner.skip(1); bond.bond_idx = _scanner.readIntFix(3) - 1; _scanner.skipSpace(); @@ -3419,9 +3419,8 @@ void MolfileLoader::_readSGroup3000(const char* str) scanner.skipSpace(); scanner.readFloat(); scanner.skipSpace(); - Vec2f* brackets = sgroup->brackets.push(); - brackets[0].set(x1, y1); - brackets[1].set(x2, y2); + std::array brackets{Vec2f(x1, y1), Vec2f(x2, y2)}; + sgroup->brackets.push_back(brackets); scanner.skip(1); // ) } else if (strcmp(entity.ptr(), "CONNECT") == 0) @@ -3545,7 +3544,7 @@ void MolfileLoader::_readSGroup3000(const char* str) if (n != 4) throw Error("CSTATE number is %d (must be 4)", n); scanner.skipSpace(); - Superatom::_BondConnection& bond = sup->bond_connections.push(); + Superatom::_BondConnection& bond = sup->bond_connections.emplace_back(); int idx = scanner.readInt() - 1; bond.bond_idx = idx; scanner.skipSpace(); diff --git a/core/indigo-core/molecule/src/molfile_saver.cpp b/core/indigo-core/molecule/src/molfile_saver.cpp index d12da6366e..ab85aecb94 100644 --- a/core/indigo-core/molecule/src/molfile_saver.cpp +++ b/core/indigo-core/molecule/src/molfile_saver.cpp @@ -987,7 +987,7 @@ void MolfileSaver::_writeGenericSGroup3000(SGroup& sgroup, int idx, Output& outp } for (i = 0; i < sgroup.brackets.size(); i++) { - Vec2f* brackets = sgroup.brackets[i]; + auto& brackets = sgroup.brackets[i]; output.printf(" BRKXYZ=(9 %f %f %f %f %f %f %f %f %f)", brackets[0].x, brackets[0].y, 0.f, brackets[1].x, brackets[1].y, 0.f, 0.f, 0.f, 0.f); } if (sgroup.brackets.size() > 0 && sgroup.brk_style > 0) @@ -1068,14 +1068,15 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query) qmol = (QueryMolecule*)(&mol); int i; - QS_DEF(Array, radicals); + using intpair = std::array; + QS_DEF(Array, radicals); QS_DEF(Array, charges); QS_DEF(Array, isotopes); QS_DEF(Array, pseudoatoms); QS_DEF(Array, atom_lists); QS_DEF(Array, unsaturated); - QS_DEF(Array, substitution_count); - QS_DEF(Array, ring_bonds); + QS_DEF(Array, substitution_count); + QS_DEF(Array, ring_bonds); _atom_mapping.clear_resize(mol.vertexEnd()); _bond_mapping.clear_resize(mol.edgeEnd()); @@ -1220,9 +1221,10 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query) if (radical != 0) { - int* r = radicals.push(); + std::array r; r[0] = i; r[1] = radical; + radicals.push_back(r); } if (qmol != 0) @@ -1233,16 +1235,18 @@ void MolfileSaver::_writeCtab2000(Output& output, BaseMolecule& mol, bool query) int rbc; if (MoleculeSavers::getRingBondCountFlagValue(*qmol, i, rbc)) { - int* r = ring_bonds.push(); + std::array r; r[0] = i; r[1] = rbc; + ring_bonds.push_back(r); } int subst; if (MoleculeSavers::getSubstitutionCountFlagValue(*qmol, i, subst)) { - int* s = substitution_count.push(); + std::array s; s[0] = i; s[1] = subst; + substitution_count.push_back(s); } } diff --git a/core/indigo-core/molecule/src/query_molecule.cpp b/core/indigo-core/molecule/src/query_molecule.cpp index ddb02bae42..e01408dfad 100644 --- a/core/indigo-core/molecule/src/query_molecule.cpp +++ b/core/indigo-core/molecule/src/query_molecule.cpp @@ -583,7 +583,10 @@ QueryMolecule::Node* QueryMolecule::Node::_und(QueryMolecule::Node* node1, Query if (node2->type == QueryMolecule::OP_AND) { while (node2->children.size() != 0) - node1->children.add(node2->children.pop()); + { + node1->children.add(node2->children.top()); + node2->children.pop_back(); + } } else node1->children.add(node2); @@ -624,7 +627,10 @@ QueryMolecule::Node* QueryMolecule::Node::_oder(QueryMolecule::Node* node1, Quer if (node2->type == QueryMolecule::OP_OR) { while (node2->children.size() != 0) - node1->children.add(node2->children.pop()); + { + node1->children.add(node2->children.top()); + node2->children.pop_back(); + } } else node1->children.add(node2); @@ -650,7 +656,7 @@ QueryMolecule::Node* QueryMolecule::Node::_nicht(QueryMolecule::Node* node) { if (node->type == QueryMolecule::OP_NOT) { - Node* res = (Node*)node->children.pop(); + Node* res = node->children.top(); delete node; return res; } diff --git a/core/indigo-core/molecule/src/smiles_loader.cpp b/core/indigo-core/molecule/src/smiles_loader.cpp index e822949d29..a61cf5c666 100644 --- a/core/indigo-core/molecule/src/smiles_loader.cpp +++ b/core/indigo-core/molecule/src/smiles_loader.cpp @@ -1072,12 +1072,12 @@ void SmilesLoader::_parseMolecule() number = next - '0'; while (_cycles.size() <= number) - _cycles.push().clear(); + _cycles.emplace_back().clear(); // closing some previously numbered atom, like the last '1' in c1ccccc1 if (_cycles[number].beg >= 0) { - bond = &_bonds.push(); + bond = &_bonds.emplace_back(); bond->dir = 0; bond->topology = 0; bond->beg = _atom_stack.top(); @@ -1189,7 +1189,7 @@ void SmilesLoader::_parseMolecule() if (!first_atom) { - bond = &_bonds.push(); + bond = &_bonds.emplace_back(); bond->beg = _atom_stack.top(); bond->end = -1; bond->type = -1; @@ -1334,7 +1334,7 @@ void SmilesLoader::_parseMolecule() else { while (_cycles.size() <= number) - _cycles.push().clear(); + _cycles.emplace_back().clear(); _cycles[number].pending_bond = _bonds.size() - 1; _cycles[number].pending_bond_str = _pending_bonds_pool.add(bond_str); _cycles[number].beg = -1; // have it already in the bond @@ -1846,7 +1846,7 @@ void SmilesLoader::_addExplicitHForStereo() if ((_atoms[i].chirality > 0) && (_bmol->getVertex(i).degree() == 2) && (_atoms[i].hydrogens == 1)) { _AtomDesc& atom = _atoms.push(_neipool); - _BondDesc* bond = &_bonds.push(); + _BondDesc* bond = &_bonds.emplace_back(); atom.label = ELEM_H; int exp_h_idx = _mol->addAtom(atom.label); @@ -1885,7 +1885,7 @@ void SmilesLoader::_addLigandsForStereo() for (int j = 0; j < num_ligands; j++) { _AtomDesc& atom = _atoms.push(_neipool); - _BondDesc* bond = &_bonds.push(); + _BondDesc* bond = &_bonds.emplace_back(); std::unique_ptr qatom; if (add_explicit_h) @@ -1914,7 +1914,7 @@ void SmilesLoader::_addLigandsForStereo() if (_atoms[i].hydrogens == 1) { _AtomDesc& atom = _atoms.push(_neipool); - _BondDesc* bond = &_bonds.push(); + _BondDesc* bond = &_bonds.emplace_back(); std::unique_ptr qatom = std::make_unique(QueryMolecule::ATOM_NUMBER, ELEM_H); std::unique_ptr qbond = std::make_unique(QueryMolecule::BOND_ORDER, BOND_SINGLE); @@ -2024,12 +2024,11 @@ void SmilesLoader::_handlePolymerRepetition(int i) std::swap(start_bond, end_bond); } - Vec2f* p = sgroup->brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); - p = sgroup->brackets.push(); - p[0].set(0, 0); - p[1].set(0, 0); + std::array v; + v[0].set(0, 0); + v[1].set(0, 0); + sgroup->brackets.push_back(v); + sgroup->brackets.push_back(v); if (_polymer_repetitions[i] > 1) { @@ -3121,6 +3120,10 @@ void SmilesLoader::_readRGroupOccurrenceRanges(const char* str, Array& rang ranges.push((beg << 16) | end); } +SmilesLoader::_AtomDesc::_AtomDesc() +{ +} + SmilesLoader::_AtomDesc::_AtomDesc(Pool::Elem>& neipool) : neighbors(neipool) { label = 0; diff --git a/core/indigo-core/reaction/base_reaction.h b/core/indigo-core/reaction/base_reaction.h index f208bb6675..dae99833bf 100644 --- a/core/indigo-core/reaction/base_reaction.h +++ b/core/indigo-core/reaction/base_reaction.h @@ -25,7 +25,6 @@ #endif #include "base_cpp/auto_iter.h" -#include "base_cpp/non_copyable.h" #include "base_cpp/obj_array.h" #include "base_cpp/ptr_pool.h" #include "molecule/base_molecule.h" @@ -64,10 +63,13 @@ namespace indigo int _side; }; - class ReactionBlock : public NonCopyable + class ReactionBlock { public: - void copy(const ReactionBlock& other) + ReactionBlock() : role(-1) + { + } + ReactionBlock(const ReactionBlock& other) { indexes.copy(other.indexes); arrows_to.copy(other.arrows_to); @@ -77,7 +79,7 @@ namespace indigo int role; }; - class DLLEXPORT BaseReaction : public NonCopyable + class DLLEXPORT BaseReaction { public: enum @@ -223,7 +225,6 @@ namespace indigo ReactionBlock& addReactionBlock() { auto& rb = _reactionBlocks.push(); - rb.copy(ReactionBlock()); return rb; } diff --git a/core/indigo-core/reaction/src/canonical_rsmiles_saver.cpp b/core/indigo-core/reaction/src/canonical_rsmiles_saver.cpp index 2e4021a48d..afc80ef048 100644 --- a/core/indigo-core/reaction/src/canonical_rsmiles_saver.cpp +++ b/core/indigo-core/reaction/src/canonical_rsmiles_saver.cpp @@ -133,7 +133,7 @@ void CanonicalRSmilesSaver::_writeMolecule(int i, CanonicalSmilesSaver& saver) for (j = 0; j < atoms.size(); j++) { - _Idx& idx = _written_atoms.push(); + _Idx& idx = _written_atoms.emplace_back(); idx.mol = i; idx.idx = atoms[j]; @@ -143,7 +143,7 @@ void CanonicalRSmilesSaver::_writeMolecule(int i, CanonicalSmilesSaver& saver) for (j = 0; j < bonds.size(); j++) { - _Idx& idx = _written_bonds.push(); + _Idx& idx = _written_bonds.emplace_back(); idx.mol = i; idx.idx = bonds[j]; diff --git a/core/indigo-core/reaction/src/reaction_enumerator_state.cpp b/core/indigo-core/reaction/src/reaction_enumerator_state.cpp index fdcc825893..e912ddf273 100644 --- a/core/indigo-core/reaction/src/reaction_enumerator_state.cpp +++ b/core/indigo-core/reaction/src/reaction_enumerator_state.cpp @@ -109,7 +109,8 @@ void ReactionEnumeratorState::ReactionMonomers::removeMonomer(int idx) } _reactant_indexes.pop(); - delete (_monomers.pop()); + delete (_monomers.top()); + _monomers.pop_back(); _deep_levels.pop(); _tube_indexes.pop(); } diff --git a/core/indigo-core/reaction/src/rsmiles_saver.cpp b/core/indigo-core/reaction/src/rsmiles_saver.cpp index 07109b1d85..0b21667c43 100644 --- a/core/indigo-core/reaction/src/rsmiles_saver.cpp +++ b/core/indigo-core/reaction/src/rsmiles_saver.cpp @@ -74,7 +74,7 @@ void RSmilesSaver::_writeMolecule(int i) for (j = 0; j < atoms.size(); j++) { - _Idx& idx = _written_atoms.push(); + _Idx& idx = _written_atoms.emplace_back(); idx.mol = i; idx.idx = atoms[j]; @@ -84,7 +84,7 @@ void RSmilesSaver::_writeMolecule(int i) for (j = 0; j < bonds.size(); j++) { - _Idx& idx = _written_bonds.push(); + _Idx& idx = _written_bonds.emplace_back(); idx.mol = i; idx.idx = bonds[j]; diff --git a/core/render2d/render_common.h b/core/render2d/render_common.h index 798fc21e22..9259fd30ec 100644 --- a/core/render2d/render_common.h +++ b/core/render2d/render_common.h @@ -272,11 +272,7 @@ namespace indigo int inversion; float implHPosWeights[4]; float upperSin, lowerSin, rightSin, leftSin; - float leftMargin, rightMargin, ypos, height; - - private: - AtomDesc(const AtomDesc& ad); }; struct Sgroup @@ -319,9 +315,6 @@ namespace indigo bool prolong; int lRing; float width; - - private: - BondEnd(const BondEnd& be); }; struct BondDescr : public Edge @@ -354,25 +347,19 @@ namespace indigo int tiTopology; int topology; int reactingCenter; - - private: - BondDescr(const BondDescr& bd); }; struct Ring { Ring(); + Ring(const Ring& r); void clear(); - Array bondEnds; Array angles; int dblBondCount; bool aromatic; Vec2f center; float radius; - - private: - Ring(const Ring& r); }; struct MoleculeRenderData diff --git a/core/render2d/render_internal.h b/core/render2d/render_internal.h index 36753bad1b..1b752ddce1 100644 --- a/core/render2d/render_internal.h +++ b/core/render2d/render_internal.h @@ -21,6 +21,7 @@ #include "base_cpp/tree.h" #include "molecule/ket_commons.h" +#include #include "render_common.h" @@ -90,12 +91,12 @@ namespace indigo void _hydroPosCorrectRepulse(); void _initAtomData(); void _initRGroups(); - void _loadBrackets(Sgroup& sg, const Array& coord); - void _placeBrackets(Sgroup& sg, const Array& atoms, Array& brackets); + void _loadBrackets(Sgroup& sg, const Array>& coord); + void _placeBrackets(Sgroup& sg, const Array& atoms, Array>& brackets); void _positionIndex(Sgroup& sg, int ti, bool lower); void _loadBracketsAuto(const SGroup& group, Sgroup& sg); - void _convertCoordinate(const Array& original, Array& converted); - void _adjustBrackets(const Array& converted, Array& placed); + void _convertCoordinate(const Array>& original, Array>& converted); + void _adjustBrackets(const Array>& converted, Array>& placed); void _prepareSGroups(); void _initSGroups(Tree& sgroups, Rect2f parent); diff --git a/core/render2d/render_item_factory.h b/core/render2d/render_item_factory.h index 27dc3dfa6f..7cb20270c0 100644 --- a/core/render2d/render_item_factory.h +++ b/core/render2d/render_item_factory.h @@ -109,6 +109,9 @@ namespace indigo private: struct Item { + Item() : id(-1) + { + } Item(int id_) : id(id_) { } diff --git a/core/render2d/src/render_cdxml.cpp b/core/render2d/src/render_cdxml.cpp index c9b8824df0..a440a248c3 100644 --- a/core/render2d/src/render_cdxml.cpp +++ b/core/render2d/src/render_cdxml.cpp @@ -154,9 +154,9 @@ void RenderParamCdxmlInterface::_renderRxns(RenderParams& params) if (params.rxns.size() != 0) for (int i = 0; i < params.rxns.size(); ++i) - rxns.push(params.rxns[i]); + rxns.push_back(params.rxns[i]); else if (params.rxn.get() != 0) - rxns.push(params.rxn.get()); + rxns.push_back(params.rxn.get()); for (int rxn_ind = 0; rxn_ind < rxns.size(); rxn_ind++) { @@ -174,9 +174,9 @@ void RenderParamCdxmlInterface::_renderMols(RenderParams& params) if (params.mols.size() != 0) for (int i = 0; i < params.mols.size(); ++i) - mols.push(params.mols[i]); + mols.push_back(params.mols[i]); else if (params.mol.get() != 0) - mols.push(params.mol.get()); + mols.push_back(params.mol.get()); Vec2f offset(0, 0); Array column_widths; diff --git a/core/render2d/src/render_common.cpp b/core/render2d/src/render_common.cpp index 0c8ba942a4..9506516517 100644 --- a/core/render2d/src/render_common.cpp +++ b/core/render2d/src/render_common.cpp @@ -239,6 +239,12 @@ Ring::Ring() clear(); } +Ring::Ring(const Ring& r) : dblBondCount(r.dblBondCount), aromatic(r.aromatic), center(r.center), radius(r.radius) +{ + bondEnds.copy(r.bondEnds); + angles.copy(r.angles); +} + void Ring::clear() { bondEnds.clear(); @@ -334,17 +340,17 @@ void RenderSettings::init(float sf, float lwf) for (int i = 0; i < NELEM(dashDot); ++i) { double val = dashDot[i] * dashUnit; - bondDashSingleOrAromatic.push(val); - bondDashDoubleOrAromatic.push(val); + bondDashSingleOrAromatic.push_back(val); + bondDashDoubleOrAromatic.push_back(val); } for (int i = 0; i < NELEM(dash); ++i) { double val = dash[i] * dashUnit; - bondDashAny.push(val); - bondDashAromatic.push(val); + bondDashAny.push_back(val); + bondDashAromatic.push_back(val); } - bondDashHydro.push(dashUnit); + bondDashHydro.push_back(dashUnit); layoutMarginHorizontal = 0.4f; layoutMarginVertical = 0.6f; diff --git a/core/render2d/src/render_context.cpp b/core/render2d/src/render_context.cpp index 9ca9069b00..038de24dcd 100644 --- a/core/render2d/src/render_context.cpp +++ b/core/render2d/src/render_context.cpp @@ -389,7 +389,7 @@ void RenderContext::scale(float s) void RenderContext::storeTransform() { - cairo_matrix_t& t = transforms.push(); + cairo_matrix_t& t = transforms.emplace_back(); cairo_get_matrix(_cr, &t); cairoCheckStatus(); } @@ -404,7 +404,7 @@ void RenderContext::restoreTransform() void RenderContext::removeStoredTransform() { - transforms.pop(); + transforms.pop_back(); } void RenderContext::resetTransform() diff --git a/core/render2d/src/render_internal.cpp b/core/render2d/src/render_internal.cpp index 6e7d02f95c..a0b74e1809 100644 --- a/core/render2d/src/render_internal.cpp +++ b/core/render2d/src/render_internal.cpp @@ -714,7 +714,8 @@ void MoleculeRenderInternal::_initSGroups(Tree& sgroups, Rect2f parent) { const Superatom& group = (Superatom&)sgroup; Sgroup& sg = _data.sgroups.push(); - QS_DEF(Array, brackets); + using vecpair = std::array; + QS_DEF(Array, brackets); _placeBrackets(sg, group.atoms, brackets); _loadBrackets(sg, brackets); int tiIndex = _pushTextItem(sg, RenderItem::RIT_SGROUP); @@ -743,7 +744,7 @@ void MoleculeRenderInternal::_initSGroups() _initSGroups(sgroups, Rect2f(_min, _max)); } -void MoleculeRenderInternal::_loadBrackets(Sgroup& sg, const Array& coord) +void MoleculeRenderInternal::_loadBrackets(Sgroup& sg, const Array>& coord) { for (int j = 0; j < coord.size(); ++j) { @@ -772,12 +773,12 @@ void MoleculeRenderInternal::_loadBrackets(Sgroup& sg, const Array& co } } -void MoleculeRenderInternal::_convertCoordinate(const Array& original, Array& converted) +void MoleculeRenderInternal::_convertCoordinate(const Array>& original, Array>& converted) { auto& left = original.at(0); auto& right = original.at(1); - auto& adjLeft = converted.push(); - auto& adjRight = converted.push(); + auto& adjLeft = converted.emplace_back(); + auto& adjRight = converted.emplace_back(); _objCoordTransform(adjLeft[0], left[0]); _objCoordTransform(adjLeft[1], left[1]); @@ -787,13 +788,13 @@ void MoleculeRenderInternal::_convertCoordinate(const Array& original, void MoleculeRenderInternal::_loadBracketsAuto(const SGroup& group, Sgroup& sg) { - Array brackets; + Array> brackets; _placeBrackets(sg, group.atoms, brackets); const bool isBracketsCoordinates = group.brackets.size() != 0 || Vec2f::distSqr(group.brackets.at(0)[0], group.brackets.at(0)[1]) > EPSILON; if (isBracketsCoordinates) { - Array temp; + Array> temp; _convertCoordinate(group.brackets, temp); _loadBrackets(sg, temp); return; @@ -815,11 +816,8 @@ void MoleculeRenderInternal::_positionIndex(Sgroup& sg, int ti, bool lower) index.bbp.addScaled(bracket.d, lower ? -yShift : yShift); } -void MoleculeRenderInternal::_placeBrackets(Sgroup& sg, const Array& atoms, Array& brackets) +void MoleculeRenderInternal::_placeBrackets(Sgroup& sg, const Array& atoms, Array>& brackets) { - auto left = brackets.push(); - auto right = brackets.push(); - Vec2f min, max, a, b; for (int i = 0; i < atoms.size(); ++i) { @@ -841,10 +839,10 @@ void MoleculeRenderInternal::_placeBrackets(Sgroup& sg, const Array& atoms, float extent = _settings.unit * 3; min.sub(Vec2f(extent, extent)); max.add(Vec2f(extent, extent)); - left[0].set(min.x, max.y); - left[1].set(min.x, min.y); - right[0].set(max.x, min.y); - right[1].set(max.x, max.y); + std::array left{Vec2f(min.x, max.y), Vec2f(min.x, min.y)}; + std::array right{Vec2f(max.x, min.y), Vec2f(max.x, max.y)}; + brackets.push_back(left); + brackets.push_back(right); } void MoleculeRenderInternal::_cloneAndFillMappings() @@ -1007,7 +1005,7 @@ float getFreeAngle(const ObjArray& pp) { Vec2f d; d.diff(pp[(j + 1) % len], pp[j]); - angle.push(atan2f(d.y, d.x)); + angle.push_back(atan2f(d.y, d.x)); } angle.qsort(dblcmp, NULL); int j0 = -1; @@ -1295,7 +1293,7 @@ void MoleculeRenderInternal::_findRings() v.rotateL(be.lang / 2); v.scale(cycleLineOffset); v.add(_ad(be.aid).pos); - vv.push(v); + vv.push_back(v); } _cw.setSingleSource(CWC_BLUE); _cw.setLineWidth(_settings.unit); @@ -1309,7 +1307,7 @@ void MoleculeRenderInternal::_findRings() Array pp; for (int j = 0; j < ring.bondEnds.size(); ++j) - pp.push().copy(_ad(_be(ring.bondEnds[j]).aid).pos); + pp.emplace_back().copy(_ad(_be(ring.bondEnds[j]).aid).pos); for (int j = 0; j < ring.bondEnds.size(); ++j) ring.center.add(pp[j]); @@ -1333,7 +1331,7 @@ void MoleculeRenderInternal::_findRings() float l = fabs(Vec2f::dot(df, be.lnorm)); if (r < 0 || l < r) r = l; - ring.angles.push(atan2(df.y, df.x)); + ring.angles.push_back(atan2(df.y, df.x)); } ring.radius = r; @@ -3423,7 +3421,7 @@ void MoleculeRenderInternal::_prepareLabelText(int aid) for (int i = v.neiBegin(); i < v.neiEnd(); i = v.neiNext(i)) { float a = _getBondEnd(aid, i).lang; - angles.push(a); + angles.push_back(a); split.push(1); } } @@ -3452,18 +3450,18 @@ void MoleculeRenderInternal::_prepareLabelText(int aid) { // if no adjacent bonds present if (rGroupAttachmentIndices.size() == 1) - attachmentDirection.push().set(0, -1); + attachmentDirection.emplace_back().set(0, -1); else if (rGroupAttachmentIndices.size() == 2) { - attachmentDirection.push().set(cos((float)M_PI / 6), -sin((float)M_PI / 6)); - attachmentDirection.push().set(cos(5 * (float)M_PI / 6), -sin(5 * (float)M_PI / 6)); + attachmentDirection.emplace_back().set(cos((float)M_PI / 6), -sin((float)M_PI / 6)); + attachmentDirection.emplace_back().set(cos(5 * (float)M_PI / 6), -sin(5 * (float)M_PI / 6)); } else { for (int j = 0; j < rGroupAttachmentIndices.size(); ++j) { float a = j * 2 * (float)M_PI / rGroupAttachmentIndices.size(); - attachmentDirection.push().set(cos(a), sin(a)); + attachmentDirection.emplace_back().set(cos(a), sin(a)); } } } @@ -3490,7 +3488,7 @@ void MoleculeRenderInternal::_prepareLabelText(int aid) Vec2f d; d.copy(_getBondEnd(aid, n).dir); d.rotateL(angles[i0] * (--split[i0])); - attachmentDirection.push(d); + attachmentDirection.push_back(d); } } // create the attachment point items diff --git a/core/render2d/src/render_item_aux.cpp b/core/render2d/src/render_item_aux.cpp index bc6e47c566..a99f3fd0a1 100644 --- a/core/render2d/src/render_item_aux.cpp +++ b/core/render2d/src/render_item_aux.cpp @@ -366,21 +366,19 @@ void RenderItemAuxiliary::_renderSimpleObject(const KETSimpleObject& simple) case KETSimpleObject::EKETRectangle: { Array pts; - pts.push() = rc.leftTop(); - pts.push() = rc.rightTop(); - pts.push() = rc.rightBottom(); - pts.push() = rc.leftBottom(); - pts.push() = rc.leftTop(); + pts.push_back(rc.leftTop()); + pts.push_back(rc.rightTop()); + pts.push_back(rc.rightBottom()); + pts.push_back(rc.leftBottom()); + pts.push_back(rc.leftTop()); _rc.drawPoly(pts); } break; case KETSimpleObject::EKETLine: { Array pts; - auto& vec1 = pts.push(); - auto& vec2 = pts.push(); - vec1 = v1; - vec2 = v2; + pts.push_back(v1); + pts.push_back(v2); _rc.drawPoly(pts); } break;