mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 16:26:18 +02:00
4feb7d9f71
Also move `SourcePath` into `libutil`. These changes allow `error.hh` and `error.cc` to access source path and position information, which we can use to produce better error messages (for example, we could consider omitting filenames when two or more consecutive stack frames originate from the same file).
111 lines
1.8 KiB
C++
111 lines
1.8 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include <compare>
|
|
#include <memory>
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
|
|
namespace nix {
|
|
|
|
/**
|
|
* A simple non-nullable reference-counted pointer. Actually a wrapper
|
|
* around std::shared_ptr that prevents null constructions.
|
|
*/
|
|
template<typename T>
|
|
class ref
|
|
{
|
|
private:
|
|
|
|
std::shared_ptr<T> p;
|
|
|
|
public:
|
|
|
|
ref(const ref<T> & r)
|
|
: p(r.p)
|
|
{ }
|
|
|
|
explicit ref<T>(const std::shared_ptr<T> & p)
|
|
: p(p)
|
|
{
|
|
if (!p)
|
|
throw std::invalid_argument("null pointer cast to ref");
|
|
}
|
|
|
|
explicit ref<T>(T * p)
|
|
: p(p)
|
|
{
|
|
if (!p)
|
|
throw std::invalid_argument("null pointer cast to ref");
|
|
}
|
|
|
|
T* operator ->() const
|
|
{
|
|
return &*p;
|
|
}
|
|
|
|
T& operator *() const
|
|
{
|
|
return *p;
|
|
}
|
|
|
|
operator std::shared_ptr<T> () const
|
|
{
|
|
return p;
|
|
}
|
|
|
|
std::shared_ptr<T> get_ptr() const
|
|
{
|
|
return p;
|
|
}
|
|
|
|
template<typename T2>
|
|
ref<T2> cast() const
|
|
{
|
|
return ref<T2>(std::dynamic_pointer_cast<T2>(p));
|
|
}
|
|
|
|
template<typename T2>
|
|
std::shared_ptr<T2> dynamic_pointer_cast() const
|
|
{
|
|
return std::dynamic_pointer_cast<T2>(p);
|
|
}
|
|
|
|
template<typename T2>
|
|
operator ref<T2> () const
|
|
{
|
|
return ref<T2>((std::shared_ptr<T2>) p);
|
|
}
|
|
|
|
bool operator == (const ref<T> & other) const
|
|
{
|
|
return p == other.p;
|
|
}
|
|
|
|
bool operator != (const ref<T> & other) const
|
|
{
|
|
return p != other.p;
|
|
}
|
|
|
|
bool operator < (const ref<T> & other) const
|
|
{
|
|
return p < other.p;
|
|
}
|
|
|
|
private:
|
|
|
|
template<typename T2, typename... Args>
|
|
friend ref<T2>
|
|
make_ref(Args&&... args);
|
|
|
|
};
|
|
|
|
template<typename T, typename... Args>
|
|
inline ref<T>
|
|
make_ref(Args&&... args)
|
|
{
|
|
auto p = std::make_shared<T>(std::forward<Args>(args)...);
|
|
return ref<T>(p);
|
|
}
|
|
|
|
}
|