#ifndef CCommandTreeNode_HPP_INCLUDED #define CCommandTreeNode_HPP_INCLUDED /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (c) 2018-2021 3Dconnexion. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ /** * @file CCommandTreeNode.hpp * @brief Tree container for CActionNode. */ #include // stdlib #include #include #include #if !_MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" #endif namespace TDx { template class raw_linkedlist_iterator { public: typedef std::input_iterator_tag iterator_category; typedef _Ty value_type; typedef ptrdiff_t difference_type; typedef _Ty *pointer; typedef _Ty &reference; public: raw_linkedlist_iterator(_Ty *_ptr = nullptr) : _MyPtr(_ptr) { } raw_linkedlist_iterator(const raw_linkedlist_iterator<_Ty> &_other) : _MyPtr(_other._MyPtr) { } raw_linkedlist_iterator<_Ty> &operator=(const raw_linkedlist_iterator<_Ty> &_other) { _MyPtr = _other._MyPtr; return *this; } raw_linkedlist_iterator<_Ty> &operator=(_Ty *_ptr) { _MyPtr = _ptr; return *this; } // accessors _Ty &operator*() { return *_MyPtr; } _Ty const &operator*() const { return *_MyPtr; } _Ty *operator->() { return _MyPtr; } _Ty const *operator->() const { return _MyPtr; } raw_linkedlist_iterator<_Ty> &operator++() { if (_MyPtr) _MyPtr = _MyPtr->GetNext(); return *this; } raw_linkedlist_iterator<_Ty> &operator--() { if (doubled_linked) { if (_MyPtr) _MyPtr = _MyPtr->GetPrevious(); } else { throw std::logic_error("Not Supported"); } return *this; } bool operator<(raw_linkedlist_iterator<_Ty> const &rhs) const { if (!_MyPtr) return false; else if (!rhs._MyPtr) return true; return (_MyPtr < rhs._MyPtr); } bool operator<=(raw_linkedlist_iterator<_Ty> const &rhs) const { if (_MyPtr == rhs._MyPtr) return true; return operator<(rhs); } bool operator>(raw_linkedlist_iterator<_Ty> const &rhs) const { return !operator<=(rhs); } bool operator>=(raw_linkedlist_iterator<_Ty> const &rhs) const { return !operator<(rhs); } operator bool() const { return _MyPtr != nullptr; } protected: _Ty *_MyPtr; }; /// /// Tree container for CActionNode. /// /// The tree is implemented as a singularly linked list. class CCommandTree : public CActionNode { public: typedef CActionNode base_type; typedef CActionNode const const_base_type; typedef CActionNode const &const_base_ref_type; typedef CActionNode const *const_base_ptr_type; typedef CCommandTree self_type; public: typedef CCommandTree &reference; typedef CCommandTree const &const_reference; typedef raw_linkedlist_iterator iterator; typedef raw_linkedlist_iterator const_iterator; CCommandTree() { } explicit CCommandTree(std::string id, std::string label, std::string description, SiActionNodeType_t type) : base_type(std::move(id), std::move(label), std::move(description), type) { } explicit CCommandTree(std::string id, std::string label, SiActionNodeType_t type) : base_type(std::move(id), std::move(label), type) { } #if defined(_MSC_VER) && _MSC_VER < 1900 CCommandTree(CCommandTree &&other) NOEXCEPT : base_type(std::forward(other)) { } CCommandTree &operator=(CCommandTree &&other) NOEXCEPT { base_type::operator=(std::forward(other)); return *this; } private: CCommandTree(const CCommandTree &) { } const CCommandTree &operator=(const CCommandTree &){}; #else CCommandTree(CCommandTree &&) = default; CCommandTree &operator=(CCommandTree &&) = default; // No copying CCommandTree(const CCommandTree &) = delete; const CCommandTree &operator=(const CCommandTree &) = delete; #endif // defined(_MSC_VER) && _MSC_VER<1900 public: void push_back(base_type &&value) { #if (defined(_MSC_VER) && _MSC_VER < 1900) std::unique_ptr node(new base_type(std::forward(value))); #else std::unique_ptr node = std::make_unique(std::forward(value)); #endif push_back(std::move(node)); } template void push_back(std::unique_ptr &&value, typename std::enable_if::value>::type * = nullptr) { base_type *last = this->GetChild(); if (!last) { PutChild(std::unique_ptr(static_cast(value.release()))); } else { while (last->GetNext() != nullptr) { last = last->GetNext(); } last->PutNext(std::unique_ptr(static_cast(value.release()))); } } void push_front(base_type &&value) { #if (defined(_MSC_VER) && _MSC_VER < 1900) std::unique_ptr node(new base_type(std::forward(value))); #else std::unique_ptr node = std::make_unique(std::forward(value)); #endif push_front(std::move(node)); } void push_front(std::unique_ptr &&value) { value->PutNext(std::unique_ptr(DetachChild())); PutChild(std::forward>(value)); } const_reference back() const { const base_type *last = this->GetChild(); if (!last) { return *this; } while (last->GetNext() != nullptr) { last = last->GetNext(); } return *static_cast(last); } reference back() { base_type *last = this->GetChild(); if (!last) { return *this; } while (last->GetNext() != nullptr) { last = last->GetNext(); } return *static_cast(last); } void clear() { base_type *head = this->DetachChild(); if (head) { head->clear(); } } const_reference front() const { const base_type *head = this->GetChild(); if (!head) { return *this; } return *static_cast(head); } reference front() { base_type *head = this->GetChild(); if (!head) { return *this; } return *static_cast(head); } const_iterator begin() const { if (empty()) { return end(); } return const_iterator(this->GetChild()); } iterator begin() { if (empty()) { return end(); } return iterator(this->GetChild()); } bool empty() const { return (this->GetChild() == nullptr); } const_iterator end() const { return nullptr; } iterator end() { return nullptr; } }; typedef CCommandTree CCommandTreeNode; } // namespace TDx #if !_MSC_VER #pragma GCC diagnostic pop #endif #endif // CCommandTreeNode_HPP_INCLUDED