Skip to content

Instantly share code, notes, and snippets.

@hisui
Last active August 29, 2015 13:59
Show Gist options
  • Save hisui/10949848 to your computer and use it in GitHub Desktop.
Save hisui/10949848 to your computer and use it in GitHub Desktop.
[iOS] Immutable vector for sharing use.
#ifndef __sf_iOS_SFSeq_hpp_
#define __sf_iOS_SFSeq_hpp_
#include <memory>
#include <vector>
#include <iostream>
namespace sf {
template<typename A> class SeqBuilder;
template<typename A> class Seq
{
friend class SeqBuilder<A>;
Seq(std::vector<A> &&raw)
:raw(std::make_shared<std::vector<A>>(std::move(raw)))
{
}
public:
Seq()
{
}
const A &operator[](size_t i) const
{
return raw->at(i);
}
size_t size() const { return raw->size(); }
using iterator = typename std::vector<A>::const_iterator;
iterator begin() const { return raw->begin(); }
iterator end() const { return raw-> end(); }
template<typename B, typename X = typename std::enable_if<std::is_convertible<B,A>{}>::type>
operator Seq<B>() const;
friend std::ostream &operator <<(std::ostream &out, const Seq<A> &o)
{
const char *sep = "";
out << "Seq(";
for (auto &e: o) {
out << sep << e, sep = ",";
}
out << ")";
return out;
}
private:
std::shared_ptr<std::vector<A>> raw;
};
template<typename A> class SeqBuilder
{
public:
SeqBuilder()
{
}
SeqBuilder(size_t capacity)
{
raw.reserve(capacity);
}
Seq<A> operator()() { return Seq<A>(std::move(raw)); }
template<typename Ty> void operator+=(Ty &&a)
{
raw.push_back(std::forward<Ty>(a));
}
private:
std::vector<A> raw;
};
template<typename A>
template<typename B, typename X>
Seq<A>::operator Seq<B>() const
{
SeqBuilder<B> builder(this->size());
for (auto &e: *this) {
builder += static_cast<B>(e);
}
return builder();
}
template<typename A> void SeqMake_0(SeqBuilder<A> &)
{
// no-op
}
template<typename A, typename ...Args> void
SeqMake_0(SeqBuilder<A> &builder, A &&a, Args &&...args)
{
builder += std::forward<A>(a);
SeqMake_0
(builder, std::forward<Args>(args)...);
}
template<typename A, typename A_ = typename std::decay<A>::type, typename ...Args>
Seq<A_> SeqMake(A &&a, Args &&...args)
{
SeqBuilder<A_> builder(1 + sizeof...(Args));
SeqMake_0(builder
, std::forward<A>(a)
, std::forward<Args>(args)...);
return builder();
}
template<typename A> Seq<A> SeqMake()
{
static sf::Seq<A> o;
return o;
}
} // namespace
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment