Last active
May 5, 2018 14:45
-
-
Save VeganPower/b5055d9e746b49ba3201f81470c077fc to your computer and use it in GitHub Desktop.
operator = inheritance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <type_traits> | |
#include <functional> | |
#include "function_traits.hpp" | |
template<typename T> | |
struct ViewTraits | |
{ | |
typedef decltype(std::declval<T>().read()) ViewValue_t; | |
}; | |
template<typename T> | |
void advance_to_first_valid(T& f) | |
{ | |
while(!f.done() && !std::invoke(f.pred, f.read())) | |
{ | |
f.next(); | |
} | |
} | |
template<typename View_t, typename Pred_t> | |
struct FilterFun : View_t | |
{ | |
typedef typename ViewTraits<View_t>::ViewValue_t ViewValue_t; | |
// typedef typename std::function<bool(ViewValue_t)> Pred_t; | |
FilterFun(View_t const& v, Pred_t p) | |
: View_t(v) | |
, pred(p) | |
{ | |
advance_to_first_valid(*this); | |
} | |
void next() | |
{ | |
View_t::next(); | |
advance_to_first_valid(*this); | |
} | |
Pred_t pred; | |
}; | |
template<typename T> | |
struct FilterOp | |
{ | |
std::function<bool(T)> params; | |
}; | |
template<typename T> | |
auto filter(T const& p) | |
{ | |
// static_assert(std::is_convertible_v<T, std::function>); | |
// static_assert(std::is_function_v<T>); // doesn't works with lambdas | |
typedef function_traits<T> PredTraits; | |
static_assert(PredTraits::arity == 1); | |
typedef typename PredTraits::template arg<0>::type Filter_type; | |
return FilterOp<Filter_type> { p }; | |
} | |
template<typename View_t, typename T> | |
auto operator |(View_t const& right, FilterOp<T> const& left) | |
{ | |
return FilterFun<View_t, decltype(left.params)>(right, left.params); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
template <typename T> | |
struct function_traits | |
: public function_traits<decltype(&T::operator())> | |
{}; | |
// For generic types, directly use the result of the signature of its 'operator()' | |
template <typename ClassType, typename ReturnType, typename... Args> | |
struct function_traits<ReturnType(ClassType::*)(Args...) const> | |
// we specialize for pointers to member function | |
{ | |
enum { arity = sizeof...(Args) }; | |
// arity is the number of arguments. | |
typedef ReturnType result_type; | |
template <size_t i> | |
struct arg | |
{ | |
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; | |
// the i-th argument is equivalent to the i-th tuple element of a tuple | |
// composed of those arguments. | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "containers/static_array.h" | |
#include <iostream> | |
#include <functional> | |
#include "filter.hpp" | |
template<typename T> | |
struct ValueRef | |
{ | |
ValueRef& operator =(T x){ | |
v = x; | |
return *this; | |
} | |
T& v; | |
}; | |
template<typename T> | |
struct PlainView | |
{ | |
T* cursor = nullptr; | |
T const* sentinel = nullptr; | |
void next() | |
{ | |
cursor++; | |
} | |
PlainView& operator =(int x) | |
{ | |
*cursor = x; | |
return *this; | |
} | |
operator ValueRef<T>() | |
{ | |
return ValueRef<T> {*cursor}; | |
} | |
operator T() const | |
{ | |
return *cursor; | |
} | |
T& read() | |
{ | |
return *cursor; | |
} | |
T const& read() const | |
{ | |
return *cursor; | |
} | |
bool done() const | |
{ | |
return cursor == sentinel; | |
} | |
}; | |
// zip | |
template<typename V1, typename V2> | |
struct ZipView | |
{ | |
V1& first; | |
V2& second; | |
void next() | |
{ | |
first.next(); | |
second.next(); | |
} | |
auto read() | |
{ | |
return std::make_tuple(first.read(), second.read()); | |
} | |
bool done() | |
{ | |
return first.done() || second.done(); | |
} | |
}; | |
template<typename View_t, typename result_type, typename filter_type> | |
struct TransformFun : public View_t | |
{ | |
TransformFun(View_t const&v, std::function<result_type(filter_type)> p) | |
: View_t(v) | |
, pred(p) | |
{} | |
result_type read() const | |
{ | |
return pred(View_t::read()); | |
} | |
std::function<result_type(filter_type)> pred; | |
}; | |
template<typename T> | |
struct TransformOp | |
{ | |
T pred; | |
}; | |
template<typename View_t, typename T> | |
auto operator |(View_t const& right, TransformOp<T> const& left) | |
{ | |
using PredTraits = function_traits<T>; | |
static_assert(PredTraits::arity == 1); | |
using filter_type = typename PredTraits::template arg<0>::type; | |
using result_type = typename PredTraits::result_type; | |
return TransformFun<View_t, result_type, filter_type>(right, left.pred); | |
} | |
template<typename T> | |
TransformOp<T> transform(T const& p) | |
{ | |
return TransformOp<T>{ p }; | |
} | |
template<typename View_t> | |
struct TakeFun : public View_t | |
{ | |
TakeFun(View_t const& v, int c) | |
: View_t(v) | |
, count(c) | |
{} | |
int count = 0; | |
void next() | |
{ | |
count--; | |
View_t::next(); | |
} | |
bool done() | |
{ | |
return (count == 0) || View_t::done(); | |
} | |
}; | |
struct TakeOp | |
{ | |
int param; | |
}; | |
template<typename View_t> | |
TakeFun<View_t> operator |(View_t const& right, TakeOp const& left) | |
{ | |
return TakeFun<View_t>(right, left.param); | |
} | |
TakeOp take(int p) | |
{ | |
return TakeOp{ p }; | |
} | |
int main() | |
{ | |
std::vector<int> a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; | |
// a.iter() | filter(x>3) | transform(x*x) | take(4) | |
PlainView<int> view = { &a[0], &a[a.size()] }; | |
for (auto t = view | |
| filter( [](int x) { return x > 3; }) | |
| transform( [](int x) -> float { return x*x+0.5f; }) | |
| take(4) | |
; | |
!t.done(); t.next() | |
) | |
{ | |
int x = t; | |
std::cout << x << "->" << t.read() << ' '; | |
(ValueRef<int>)t = 0; | |
// t = 0; | |
} | |
vstl::StaticArray<int> b = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; | |
PlainView<int> view_b = { &b[0], &b[b.size()] }; | |
ZipView<PlainView<int>, PlainView<int>> zip = { view, view_b}; | |
for (auto z = zip | take(8); !z.done(); z.next()) | |
{ | |
auto t = z.read(); | |
std::cout << "\n "; | |
std::cout << "{ " << std::get<0>(t) << ", " << std::get<1>(t) << " }"; | |
} | |
std::cout << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment