wxMaxima
CellList.h
Go to the documentation of this file.
1 // -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 //
3 // Copyright (C) 2020 Kuba Ober <kuba@bertec.com>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 // SPDX-License-Identifier: GPL-2.0+
21 
30 #ifndef WXMAXIMA_CELLLIST_H
31 #define WXMAXIMA_CELLLIST_H
32 
33 #include "CellPtr.h"
34 #include <memory>
35 
37 {
38 protected:
39  std::unique_ptr<Cell> m_head;
40  Cell *m_tail = {};
41  Cell *m_lastAppended = {};
42 
44  void base_Append(std::unique_ptr<Cell> &&cells);
45 
49  Cell *base_DynamicAppend(std::unique_ptr<Cell> &&cells,
50  Cell *(*caster)(Cell *));
51 
53  void ClearLastAppended() { m_lastAppended = {}; }
54 };
55 
57 template <typename T = Cell> class CellListBuilder : CellListBuilderBase
58 {
59  static Cell *DynamicCast(Cell *cell) { return dynamic_cast<T *>(cell); }
60 
61 public:
63 
65  explicit operator bool() const { return bool(m_head); }
66 
68  operator std::unique_ptr<T>() && { return TakeHead(); }
69 
78  {
79  T *ptr = dynamic_cast<T *>(m_head.get());
80  if (ptr) {
81  m_head.release();
82  m_tail = {};
83  m_lastAppended = {};
84  } else
85  m_head.reset();
86 
87  wxASSERT(!m_head && !m_tail && !m_lastAppended); //-V614
88  return ptr;
89  }
90 
92  std::unique_ptr<T> TakeHead()
93  {
94  m_tail = {};
95  m_lastAppended = {};
96  auto retval = dynamic_unique_ptr_cast<T>(std::move(m_head));
97 
98  wxASSERT(!m_head && !m_tail && !m_lastAppended);
99  return retval;
100  }
101 
103  T *GetTail() const { return dynamic_cast<T*>(m_tail); }
104 
106  T *GetLastAppended() const { return dynamic_cast<T*>(m_lastAppended); }
107 
109  // cppcheck-suppress deallocret
110  T *Append(T *cells)
111  {
112  base_Append(std::unique_ptr<Cell>(cells));
113  return cells;
114  }
115 
119  T *DynamicAppend(Cell *cells)
120  {
121  return static_cast<T *>(
122  base_DynamicAppend(std::unique_ptr<Cell>(cells), DynamicCast));
123  }
124 
128  T *DynamicAppend(std::unique_ptr<Cell> &&cells)
129  {
130  return static_cast<T *>(base_DynamicAppend(std::move(cells), DynamicCast));
131  }
132 
134  T *Append(std::unique_ptr<T> &&cells)
135  {
136  auto *const retval = cells.get();
137  base_Append(std::move(cells));
138  return retval;
139  }
140 };
141 
142 class CellList
143 {
144 public:
145 
148  static void Check(const Cell *cell);
149  static void Check(const GroupCell *cell);
150 
157  static std::unique_ptr<Cell> SetNext(Cell *cell, std::unique_ptr<Cell> &&next);
158 
163  static void DeleteList(Cell *afterMe);
164 
170  static void AppendCell(Cell *cell, std::unique_ptr<Cell> &&tail);
171 
172  template <typename T>
173  static void AppendCell(const std::unique_ptr<T> &cell, std::unique_ptr<Cell> &&tail)
174  { AppendCell(cell.get(), std::move(tail)); }
175 
176  struct SplicedIn
177  {
181  };
182 
191  static SplicedIn SpliceInAfter(Cell *where, std::unique_ptr<Cell> &&head, Cell *last = nullptr);
192 
193  struct TornOut {
198  std::unique_ptr<Cell> cellOwner;
201  std::unique_ptr<Cell> tailOwner;
202  };
203 
211  static TornOut TearOut(Cell *first, Cell *last);
212 };
213 
214 #endif
CellListBuilder::GetLastAppended
T * GetLastAppended() const
Provides the most cell passed to the most recent Append call.
Definition: CellList.h:106
CellPtr< Cell >
CellListBuilder::DynamicAppend
T * DynamicAppend(std::unique_ptr< Cell > &&cells)
Definition: CellList.h:128
CellPtr.h
CellList::TearOut
static TornOut TearOut(Cell *first, Cell *last)
Definition: CellList.cpp:158
CellList::TornOut::tailOwner
std::unique_ptr< Cell > tailOwner
Definition: CellList.h:201
CellListBuilder::TakeHead
std::unique_ptr< T > TakeHead()
Passes on the ownership of the list head.
Definition: CellList.h:92
CellListBuilder::Append
T * Append(std::unique_ptr< T > &&cells)
Appends one or more cells.
Definition: CellList.h:134
CellListBuilder
Manages building a list of cells, keeping the head and tail of the list.
Definition: CellList.h:57
CellList::SplicedIn::lastSpliced
Cell * lastSpliced
Definition: CellList.h:180
CellList::TornOut
Definition: CellList.h:193
CellList
Definition: CellList.h:142
CellList::TornOut::cellOwner
std::unique_ptr< Cell > cellOwner
Definition: CellList.h:198
CellList::Check
static void Check(const Cell *cell)
Definition: CellList.cpp:55
CellList::DeleteList
static void DeleteList(Cell *afterMe)
Definition: CellList.cpp:86
Cell
Definition: Cell.h:139
CellListBuilderBase
Definition: CellList.h:36
CellListBuilderBase::base_Append
void base_Append(std::unique_ptr< Cell > &&cells)
Appends one or more cells.
Definition: CellList.cpp:25
CellList::SpliceInAfter
static SplicedIn SpliceInAfter(Cell *where, std::unique_ptr< Cell > &&head, Cell *last=nullptr)
Definition: CellList.cpp:124
CellList::AppendCell
static void AppendCell(Cell *cell, std::unique_ptr< Cell > &&tail)
Definition: CellList.cpp:95
CellList::TornOut::cell
CellPtr< Cell > cell
The first in the torn-out list of cells, or null if the tearing out had failed.
Definition: CellList.h:195
CellListBuilder::GetTail
T * GetTail() const
Provides the last cell in the list (if any).
Definition: CellList.h:103
CellList::SetNext
static std::unique_ptr< Cell > SetNext(Cell *cell, std::unique_ptr< Cell > &&next)
Definition: CellList.cpp:62
CellListBuilderBase::ClearLastAppended
void ClearLastAppended()
Clears the pointer to the last appended cell. Useful when tree building.
Definition: CellList.h:53
CellListBuilder::Append
T * Append(T *cells)
Appends one or more cells.
Definition: CellList.h:110
CellListBuilder::DynamicAppend
T * DynamicAppend(Cell *cells)
Definition: CellList.h:119
CellListBuilder::ReleaseHead
T * ReleaseHead()
Definition: CellList.h:77
CellList::SplicedIn
Definition: CellList.h:176
GroupCell
Definition: GroupCell.h:68
CellListBuilderBase::base_DynamicAppend
Cell * base_DynamicAppend(std::unique_ptr< Cell > &&cells, Cell *(*caster)(Cell *))
Definition: CellList.cpp:42