Skip to content

Instantly share code, notes, and snippets.

@skyrpex
Last active August 29, 2015 13:56
Show Gist options
  • Save skyrpex/9001125 to your computer and use it in GitHub Desktop.
Save skyrpex/9001125 to your computer and use it in GitHub Desktop.
#pragma once
#include <memory>
namespace stx
{
namespace
{
template <class T>
bool operator==(const std::unique_ptr<T> &a, const T *b)
{
return a.get() == b;
}
}
template <typename InputIterator, typename T>
int index_of(InputIterator first, InputIterator last, const T &value)
{
int i = 0;
while (first != last) {
if (*first == value)
return i;
++i;
++first;
}
return -1;
}
template <typename Container, typename T>
int index_of(const Container &container, const T &value)
{
return index_of(container.begin(), container.end(), value);
}
}
#pragma once
#include <memory>
namespace stx
{
template <typename T>
class cow_ptr
{
public:
cow_ptr() = default;
cow_ptr(const cow_ptr<T> &) = default;
cow_ptr(cow_ptr<T> &&) = default;
cow_ptr(std::shared_ptr<T> &&ptr)
: m_ptr(ptr)
{
}
cow_ptr(T *ptr)
: cow_ptr(std::shared_ptr<T>(ptr))
{
}
cow_ptr &operator=(const cow_ptr<T> &) = default;
cow_ptr &operator=(cow_ptr<T> &&) = default;
cow_ptr &operator=(std::shared_ptr<T> &&ptr)
{
m_ptr = ptr;
}
void detach()
{
if (!m_ptr.unique())
m_ptr.reset(new T(*m_ptr));
}
T &operator*()
{
detach();
return m_ptr.operator*();
}
const T &operator*() const
{
return m_ptr.operator*();
}
T *operator->()
{
detach();
return m_ptr.operator->();
}
const T *operator->() const
{
return m_ptr.operator->();
}
private:
std::shared_ptr<T> m_ptr;
};
template <typename T, typename ...Args>
cow_ptr<T> make_cow(Args &&...args)
{
return cow_ptr<T>(std::make_shared<T>(args...));
}
template <typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args &&...args)
{
return std::unique_ptr<T>(new T(args...));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment