2018-04-17 19:28:25 +02:00
|
|
|
#ifndef FORTRAN_PARSER_REFERENCE_COUNTED_H_
|
|
|
|
#define FORTRAN_PARSER_REFERENCE_COUNTED_H_
|
|
|
|
|
|
|
|
// A template class of smart pointers to objects with their own
|
|
|
|
// reference counting object lifetimes that's lighter weight
|
|
|
|
// than std::shared_ptr<>. Not thread-safe.
|
|
|
|
|
|
|
|
namespace Fortran {
|
|
|
|
namespace parser {
|
|
|
|
|
|
|
|
template<typename A> class ReferenceCounted {
|
|
|
|
public:
|
|
|
|
ReferenceCounted() {}
|
|
|
|
void TakeReference() { ++references_; }
|
|
|
|
void DropReference() {
|
|
|
|
if (--references_ == 0) {
|
2018-04-17 23:45:43 +02:00
|
|
|
delete static_cast<A *>(this);
|
2018-04-17 19:28:25 +02:00
|
|
|
}
|
|
|
|
}
|
2018-04-17 23:45:43 +02:00
|
|
|
|
2018-04-17 19:28:25 +02:00
|
|
|
private:
|
|
|
|
int references_{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename A> class CountedReference {
|
|
|
|
public:
|
|
|
|
using type = A;
|
|
|
|
CountedReference() {}
|
|
|
|
CountedReference(type *m) : p_{m} { Take(); }
|
|
|
|
CountedReference(const CountedReference &c) : p_{c.p_} { Take(); }
|
|
|
|
CountedReference(CountedReference &&c) : p_{c.p_} { c.p_ = nullptr; }
|
|
|
|
CountedReference &operator=(const CountedReference &c) {
|
2018-04-17 20:16:05 +02:00
|
|
|
c.Take();
|
2018-04-17 19:28:25 +02:00
|
|
|
Drop();
|
|
|
|
p_ = c.p_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
CountedReference &operator=(CountedReference &&c) {
|
2018-04-17 20:16:05 +02:00
|
|
|
A *p{c.p_};
|
2018-04-17 19:28:25 +02:00
|
|
|
c.p_ = nullptr;
|
2018-04-17 20:16:05 +02:00
|
|
|
Drop();
|
|
|
|
p_ = p;
|
2018-04-17 19:28:25 +02:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
~CountedReference() { Drop(); }
|
|
|
|
operator bool() const { return p_ != nullptr; }
|
|
|
|
type *get() const { return p_; }
|
|
|
|
type &operator*() const { return *p_; }
|
|
|
|
type *operator->() const { return p_; }
|
|
|
|
|
|
|
|
private:
|
2018-04-17 20:16:05 +02:00
|
|
|
void Take() const {
|
2018-04-17 19:28:25 +02:00
|
|
|
if (p_) {
|
|
|
|
p_->TakeReference();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void Drop() {
|
|
|
|
if (p_) {
|
|
|
|
p_->DropReference();
|
|
|
|
p_ = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type *p_{nullptr};
|
|
|
|
};
|
|
|
|
} // namespace parser
|
|
|
|
} // namespace Fortran
|
|
|
|
#endif // FORTRAN_PARSER_REFERENCE_COUNTED_H_
|