1#ifndef FREE_TENSOR_SUB_TREE_H
2#define FREE_TENSOR_SUB_TREE_H
28#define DEFINE_AST_PART_ACCESS(part) \
32 friend class Allocator<part>;
57 std::atomic_flag
lock_ = ATOMIC_FLAG_INIT;
60 while (
lock_.test_and_set(std::memory_order_acquire)) {
121 virtual bool isAST()
const {
return false; };
134template <
class T, NullPolicy POLICY = NullPolicy::NotNull>
class SubTree {
143 template <
class, NullPolicy>
friend class SubTree;
148 if (
auto p = obj_->parent(); p.
isValid()) {
157 if (obj_.
isValid() && parent_ !=
nullptr) {
158 while (!obj_->trySetParent(
159 ((EnableSelf<typename T::Self> *)parent_)->self())) {
160 obj_ =
deepCopy(obj_).template as<T>();
167 ERROR(
"Cannot assign a null Ref to a NotNull SubTree");
179 if (obj_->isSubTree()) {
180 obj_ =
deepCopy(obj).template as<T>();
182 ASSERT(!obj_->isSubTree());
188 if (obj_->isSubTree()) {
189 obj_ =
deepCopy(obj).template as<T>();
191 ASSERT(!obj_->isSubTree());
204 : obj_(
std::move(other.obj_)), parent_(other.parent_) {
205 other.parent_ =
nullptr;
208 template <NullPolicy OTHER_POLICY>
210 : obj_(
std::move(other.obj_)), parent_(other.parent_) {
211 other.parent_ =
nullptr;
224 if (other.obj_.isValid()) {
225 obj_ =
deepCopy(other.obj_).template as<T>();
226 ASSERT(!obj_->isSubTree());
232 template <NullPolicy OTHER_POLICY>
234 if (other.obj_.isValid()) {
235 obj_ =
deepCopy(other.obj_).template as<T>();
236 ASSERT(!obj_->isSubTree());
246 obj_ = std::move(other.obj_);
251 template <NullPolicy OTHER_POLICY>
254 obj_ = std::move(other.obj_);
262 if (other.obj_.isValid()) {
263 obj_ =
deepCopy(other.obj_).template as<T>();
264 ASSERT(!obj_->isSubTree());
272 template <NullPolicy OTHER_POLICY>
275 if (other.obj_.isValid()) {
276 obj_ =
deepCopy(other.obj_).template as<T>();
277 ASSERT(!obj_->isSubTree());
287 requires std::derived_from<T, U>
295 template <
class U>
Ref<U> as()
const {
return obj_.template as<U>(); }
305template <
class T, NullPolicy POLICY = NullPolicy::NotNull>
class SubTreeList {
306 std::vector<SubTree<T, POLICY>> objs_;
314 template <
class, NullPolicy>
friend class SubTree;
319 template <std::derived_from<T> U>
321 objs_.reserve(objs.size());
322 for (
auto &&item : objs) {
325 objs_.emplace_back(std::move(newItem));
329 objs_.reserve(objs.size());
330 for (
auto &&item : objs) {
332 newItem = std::move(item);
333 objs_.emplace_back(std::move(newItem));
336 template <std::derived_from<T> U>
338 objs_.reserve(objs.size());
339 for (
auto &&item : objs) {
341 newItem = std::move(item);
342 objs_.emplace_back(std::move(newItem));
354 : objs_(
std::move(other.objs_)), parent_(other.parent_) {
355 other.parent_ =
nullptr;
357 template <NullPolicy OTHER_POLICY>
359 objs_.reserve(other.objs_.size());
360 for (
auto &&item : other.objs_) {
361 objs_.emplace_back(std::move(item));
364 other.parent_ =
nullptr;
377 objs_.reserve(other.objs_.size());
378 for (
auto &&item : other.objs_) {
381 objs_.emplace_back(std::move(newItem));
384 template <NullPolicy OTHER_POLICY>
386 objs_.reserve(other.objs_.size());
387 for (
auto &&item : other.objs_) {
390 objs_.emplace_back(std::move(newItem));
397 objs_.reserve(other.objs_.size());
398 for (
auto &&item : other.objs_) {
400 newItem = std::move(item);
401 objs_.emplace_back(std::move(newItem));
407 objs_.reserve(other.objs_.size());
408 for (
auto &&item : other.objs_) {
411 objs_.emplace_back(std::move(newItem));
416 template <NullPolicy OTHER_POLICY>
419 objs_.reserve(other.objs_.size());
420 for (
auto &&item : other.objs_) {
422 newItem = std::move(item);
423 objs_.emplace_back(std::move(newItem));
427 template <NullPolicy OTHER_POLICY>
430 objs_.reserve(other.objs_.size());
431 for (
auto &&item : other.objs_) {
434 objs_.emplace_back(std::move(newItem));
441 objs_.reserve(objs.size());
442 for (
auto &&item : objs) {
444 newItem = std::move(item);
445 objs_.emplace_back(std::move(newItem));
451 requires std::derived_from<T, U>
452 operator std::vector<Ref<U>>()
const {
453 return std::vector<Ref<U>>(objs_.begin(), objs_.end());
456 auto begin() {
return objs_.begin(); }
457 auto begin()
const {
return objs_.begin(); }
458 auto end() {
return objs_.end(); }
459 auto end()
const {
return objs_.end(); }
461 auto rbegin()
const {
return objs_.rbegin(); }
462 auto rend() {
return objs_.rend(); }
463 auto rend()
const {
return objs_.rend(); }
464 auto size()
const {
return objs_.size(); }
465 auto empty()
const {
return objs_.empty(); }
467 return objs_[std::forward<U>(i)];
470 return objs_[std::forward<U>(i)];
472 template <
class U>
auto &
at(U &&i) {
return objs_.at(std::forward<U>(i)); }
473 template <
class U>
const auto &
at(U &&i)
const {
474 return objs_.at(std::forward<U>(i));
476 auto &
front() {
return objs_.front(); }
477 const auto &
front()
const {
return objs_.front(); }
478 auto &
back() {
return objs_.back(); }
479 const auto &
back()
const {
return objs_.back(); }
481 objs_.emplace_back(std::forward<U>(x));
484 objs_.push_back(std::forward<U>(x));
486 template <
class... U>
auto insert(U &&...i) {
487 return objs_.insert(std::forward<U>(i)...);
489 template <
class U>
auto erase(U &&i) {
490 return objs_.erase(std::forward<U>(i));
494 objs_.reserve(std::forward<U>(x));
502Ref<ASTPart>
lca(
const Ref<ASTPart> &
lhs,
const Ref<ASTPart> &
rhs);
Definition: sub_tree.h:50
virtual bool isAST() const
Definition: sub_tree.h:121
ASTPart & operator=(ASTPart &&)
Definition: sub_tree.h:80
bool trySetParent(const Ref< ASTPart > &parent)
Definition: sub_tree.h:83
size_t hash()
Definition: sub_tree.cc:13
bool isSubTree() const
Definition: sub_tree.h:100
ASTPart(const ASTPart &other)
Definition: sub_tree.h:76
void resetHash()
Definition: sub_tree.cc:22
ASTPart(ASTPart &&other)
Definition: sub_tree.h:75
ASTPart & operator=(const ASTPart &)
Definition: sub_tree.h:81
virtual ~ASTPart()
Definition: sub_tree.h:71
virtual void compHash()=0
size_t hash_
Definition: sub_tree.h:56
std::atomic_flag lock_
Definition: sub_tree.h:57
void unlock()
Definition: sub_tree.h:65
Ref< ASTPart > parent() const
Definition: sub_tree.h:99
virtual void modifiedHook()
Definition: sub_tree.h:117
void resetParent()
Definition: sub_tree.h:94
void lock()
Definition: sub_tree.h:59
int depth() const
Definition: sub_tree.cc:5
bool isValid() const
Definition: ref.h:89
T * get() const
Definition: ref.h:101
Definition: sub_tree.h:305
const auto & operator[](U &&i) const
Definition: sub_tree.h:469
auto rbegin()
Definition: sub_tree.h:460
const auto & front() const
Definition: sub_tree.h:477
void clear()
Definition: sub_tree.h:496
auto & at(U &&i)
Definition: sub_tree.h:472
auto erase(U &&i)
Definition: sub_tree.h:489
SubTreeList(std::initializer_list< Ref< U > > objs)
Definition: sub_tree.h:337
auto rend() const
Definition: sub_tree.h:463
void pop_back()
Definition: sub_tree.h:492
void push_back(U &&x)
Definition: sub_tree.h:483
auto & operator[](U &&i)
Definition: sub_tree.h:466
SubTreeList(const SubTreeList &other)
Definition: sub_tree.h:376
auto end() const
Definition: sub_tree.h:459
SubTreeList(const ChildOf &c)
Definition: sub_tree.h:317
void reserve(U &&x)
Definition: sub_tree.h:493
auto begin()
Definition: sub_tree.h:456
SubTreeList & operator=(std::initializer_list< Ref< T > > &&objs)
Definition: sub_tree.h:439
const auto & back() const
Definition: sub_tree.h:479
SubTreeList(std::vector< Ref< U > > &&objs)
Definition: sub_tree.h:328
auto & back()
Definition: sub_tree.h:478
auto empty() const
Definition: sub_tree.h:465
SubTreeList(const std::vector< Ref< U > > &objs)
Definition: sub_tree.h:320
SubTreeList & operator=(const SubTreeList< T, OTHER_POLICY > &other)
Definition: sub_tree.h:428
auto begin() const
Definition: sub_tree.h:457
auto & front()
Definition: sub_tree.h:476
SubTreeList(const SubTreeList< T, OTHER_POLICY > &other)
Definition: sub_tree.h:385
auto end()
Definition: sub_tree.h:458
auto rend()
Definition: sub_tree.h:462
auto size() const
Definition: sub_tree.h:464
auto insert(U &&...i)
Definition: sub_tree.h:486
const auto & at(U &&i) const
Definition: sub_tree.h:473
SubTreeList & operator=(SubTreeList &&other)
Definition: sub_tree.h:395
SubTreeList & operator=(const SubTreeList &other)
Definition: sub_tree.h:405
SubTreeList(SubTreeList &&other)
Definition: sub_tree.h:353
auto rbegin() const
Definition: sub_tree.h:461
void emplace_back(U &&x)
Definition: sub_tree.h:480
SubTreeList(SubTreeList< T, OTHER_POLICY > &&other)
Definition: sub_tree.h:358
SubTreeList & operator=(SubTreeList< T, OTHER_POLICY > &&other)
Definition: sub_tree.h:417
Definition: sub_tree.h:134
~SubTree()
Definition: sub_tree.h:173
Ref< U > as() const
Definition: sub_tree.h:295
bool isValid() const
Definition: sub_tree.h:297
T & operator*() const
Definition: sub_tree.h:292
SubTree(Ref< U > &&obj)
Definition: sub_tree.h:186
SubTree(std::nullptr_t)
Definition: sub_tree.h:175
SubTree & operator=(SubTree &&other)
Definition: sub_tree.h:244
SubTree(const ChildOf &c)
Definition: sub_tree.h:172
SubTree(SubTree< T, OTHER_POLICY > &&other)
Definition: sub_tree.h:209
T * operator->() const
Definition: sub_tree.h:293
SubTree(const SubTree &other)
Definition: sub_tree.h:223
SubTree & operator=(SubTree< T, OTHER_POLICY > &&other)
Definition: sub_tree.h:252
SubTree & operator=(const SubTree &other)
Definition: sub_tree.h:260
SubTree(const SubTree< T, OTHER_POLICY > &other)
Definition: sub_tree.h:233
SubTree & operator=(const SubTree< T, OTHER_POLICY > &other)
Definition: sub_tree.h:273
SubTree(const Ref< U > &obj)
Definition: sub_tree.h:177
SubTree(SubTree &&other)
Definition: sub_tree.h:203
Ref< T > lock() const
Definition: ref.h:142
bool isValid() const
Definition: ref.h:140
#define ASSERT(expr)
Definition: except.h:152
#define ERROR(msg)
Definition: except.h:141
Definition: allocator.h:9
auto && lhs
Definition: const_fold.cc:70
Ref< ASTPart > lca(const Ref< ASTPart > &lhs, const Ref< ASTPart > &rhs)
Definition: sub_tree.cc:31
Expr deepCopy(const Expr &op)
Definition: ast.cc:364
auto auto && rhs
Definition: const_fold.cc:70
NullPolicy
Definition: sub_tree.h:124
@ NotNull
Definition: sub_tree.h:124
@ Nullable
Definition: sub_tree.h:124
Definition: sub_tree.h:20
ASTPart * parent_
Definition: sub_tree.h:21
#define DEFINE_AST_PART_ACCESS(part)
Definition: sub_tree.h:28