Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added readme more files initial files more coming
- Loading branch information
saad_attieh
committed
Jan 15, 2018
1 parent
3d22282
commit 8b021f6
Showing
7 changed files
with
348 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
# We'll use defaults from the google style, but with 4 columns indentation. | ||
BasedOnStyle: google | ||
IndentWidth: 4 | ||
--- |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#ifndef LAZYCODE_FILTERRANGE_H_ | ||
#define LAZYCODE_FILTERRANGE_H_ | ||
#include <utility> | ||
#include "rangeBase.h" | ||
namespace LazyCode { | ||
template <typename Child, typename RangeReturnType, bool isRef> | ||
class FilterRangeValueOrRef; | ||
|
||
template <typename Child, typename RangeReturnType> | ||
class FilterRangeValueOrRef<Child, RangeReturnType, false> : public RangeBase { | ||
inline auto& thisChild() { return static_cast<Child&>(*this); } | ||
|
||
RmRef<RangeReturnType> value; | ||
|
||
protected: | ||
inline RangeReturnType& assignValue() { | ||
this->value = thisChild().range.getValue(); | ||
return value; | ||
} | ||
|
||
public: | ||
inline RangeReturnType& getValue() { return value; } | ||
}; | ||
|
||
template <typename Child, typename RangeReturnType> | ||
class FilterRangeValueOrRef<Child, RangeReturnType, true> : public RangeBase { | ||
inline auto& thisChild() { return static_cast<Child&>(*this); } | ||
|
||
protected: | ||
inline auto& assignValue() { return thisChild().range.getValue(); } | ||
|
||
public: | ||
inline auto& getValue() { return thisChild().range.getValue(); } | ||
}; | ||
|
||
template <typename Range> | ||
using RangeReturnType = decltype(std::declval<Range>().getValue()); | ||
|
||
template <typename Range, typename Func> | ||
class FilterRange | ||
: public FilterRangeValueOrRef<FilterRange<Range, Func>, | ||
RangeReturnType<Range>, | ||
IsRef<RangeReturnType<Range>>::value> { | ||
typedef FilterRangeValueOrRef<FilterRange<Range, Func>, | ||
RangeReturnType<Range>, | ||
IsRef<RangeReturnType<Range>>::value> | ||
BaseType; | ||
using BaseType::assignValue; | ||
|
||
public: | ||
Range range; | ||
Func func; | ||
bool valueFound = false; | ||
|
||
public: | ||
FilterRange(RmRef<Range>&& range, Func func) | ||
: range(std::move(range)), func(func) {} | ||
FilterRange(RmRef<Range>& range, Func func) : range(range), func(func) {} | ||
|
||
inline bool hasValue() { | ||
if (!range.hasValue()) { | ||
return false; | ||
} else if (valueFound) { | ||
return true; | ||
} | ||
valueFound = func(assignValue()); | ||
if (!valueFound) { | ||
moveNext<false>(); | ||
} | ||
return valueFound; | ||
} | ||
|
||
template <bool check = true> | ||
inline void moveNext() { | ||
valueFound = false; | ||
if (check && !range.hasValue()) { | ||
return; | ||
} | ||
bool rangeHasValue; | ||
do { | ||
range.moveNext(); | ||
rangeHasValue = range.hasValue(); | ||
if (rangeHasValue) { | ||
valueFound = func(assignValue()); | ||
} else { | ||
valueFound = false; | ||
} | ||
} while (rangeHasValue && !valueFound); | ||
} | ||
|
||
inline auto begin() { | ||
return RangeIterator<FilterRange<Range, Func>>(*this); | ||
} | ||
inline auto end() { return RangeIterator<FilterRange<Range, Func>>(*this); } | ||
}; | ||
|
||
template <typename Func, typename Range, EnableIfRange<Range> = 0> | ||
inline auto filter(Func&& func, Range&& range) { | ||
return FilterRange<Range, RmRef<Func>>(std::forward<Range>(range), | ||
std::forward<Func>(func)); | ||
} | ||
|
||
template <typename Func, typename Container, EnableIfNotRange<Container> = 0> | ||
inline auto filter(Func&& func, Container&& container) { | ||
return filter(std::forward<Func>(func), | ||
toRange(std::forward<Container>(container))); | ||
} | ||
template <typename Func> | ||
class FilterBuilder { | ||
Func func; | ||
|
||
public: | ||
FilterBuilder(Func func) : func(func) {} | ||
template <typename T> | ||
friend inline auto operator|(T&& iterable, | ||
const FilterBuilder<Func>& builder) { | ||
return filter(builder.func, std::forward<T>(iterable)); | ||
} | ||
}; | ||
|
||
template <typename Func> | ||
inline FilterBuilder<Func> filter(Func&& func) { | ||
return FilterBuilder<Func>(std::forward<Func>(func)); | ||
} | ||
|
||
} // namespace LazyCode | ||
#endif /* LAZYCODE_FILTERRANGE_H_*/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef LAZYCODE_LAZYCODE_H_ | ||
#define LAZYCODE_LAZYCODE_H_ | ||
#include "filterRange.h" | ||
#include "mapRange.h" | ||
#include "rangeBase.h" | ||
#endif /* LAZYCODE_LAZYCODE_H_*/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <iterator> | ||
#include <type_traits> | ||
|
||
namespace LazyCode { | ||
|
||
template <typename T> | ||
using RmRef = typename std::remove_reference<T>::type; | ||
|
||
template <typename Iterator> | ||
class IterRange { | ||
Iterator first; | ||
Iterator last; | ||
|
||
public: | ||
IterRange(const Iterator& first, const Iterator& last) | ||
: first(first), last(last) {} | ||
|
||
inline Iterator begin() { return first; } | ||
inline Iterator end() { return last; } | ||
|
||
inline bool hasValue() { return first != last; } | ||
inline decltype(auto) getValue() { return *first; } | ||
inline void moveNext() { ++first; } | ||
}; | ||
|
||
template <typename Iterator> | ||
IterRange<Iterator> iterRange(const Iterator& first, const Iterator& last) { | ||
return IterRange<RmRef<Iterator>>(first, last); | ||
} | ||
|
||
template <typename Range> | ||
class MapRange { | ||
Range range; | ||
|
||
public: | ||
template <typename std::enable_if< | ||
std::is_same<RmRef<Range>, Range>::value int>::type = 0> | ||
MapRange(Range&& range) : range(std::move(range)) {} | ||
|
||
MapIterator(const Iterator& other) : Iterator(other) {} | ||
inline auto operator*() { | ||
// the auto is not a reference so return value will be copied | ||
return Iterator::operator*(); | ||
} | ||
}; | ||
|
||
template <typename Container> | ||
auto map(Container&& container) { | ||
typedef RmRef<decltype(std::begin(container))> IterBeginType; | ||
typedef RmRef<decltype(std::end(container))> IterEndType; | ||
return iterRange(MapIterator<IterBeginType>(std::begin(container)), | ||
MapIterator<IterEndType>(std::end(container))); | ||
} | ||
|
||
} // namespace LazyCode |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#ifndef LAZYCODE_MAPRANGE_H_ | ||
#define LAZYCODE_MAPRANGE_H_ | ||
#include "rangeBase.h" | ||
namespace LazyCode { | ||
|
||
template <typename Range, typename Func> | ||
class MapRange : public RangeBase { | ||
Range range; | ||
Func func; | ||
|
||
public: | ||
MapRange(RmRef<Range>&& range, Func func) | ||
: range(std::move(range)), func(func) {} | ||
|
||
MapRange(RmRef<Range>& range, Func func) : range(range), func(func) {} | ||
|
||
inline bool hasValue() { return range.hasValue(); } | ||
inline void moveNext() { range.moveNext(); } | ||
inline decltype(auto) getValue() { return func(range.getValue()); } | ||
|
||
inline auto begin() { return RangeIterator<MapRange<Range, Func>>(*this); } | ||
inline auto end() { return RangeIterator<MapRange<Range, Func>>(*this); } | ||
}; | ||
|
||
template <typename Func, typename Range, EnableIfRange<Range> = 0> | ||
inline auto map(Func&& func, Range&& range) { | ||
return MapRange<Range, RmRef<Func>>(std::forward<Range>(range), | ||
std::forward<Func>(func)); | ||
} | ||
|
||
template <typename Func, typename Container, EnableIfNotRange<Container> = 0> | ||
inline auto map(Func&& func, Container&& container) { | ||
return map(std::forward<Func>(func), | ||
toRange(std::forward<Container>(container))); | ||
} | ||
template <typename Func> | ||
class MapBuilder { | ||
Func func; | ||
|
||
public: | ||
MapBuilder(Func func) : func(func) {} | ||
template <typename T> | ||
friend inline auto operator|(T&& iterable, | ||
const MapBuilder<Func>& builder) { | ||
return map(builder.func, std::forward<T>(iterable)); | ||
} | ||
}; | ||
|
||
template <typename Func> | ||
inline MapBuilder<Func> map(Func&& func) { | ||
return MapBuilder<Func>(std::forward<Func>(func)); | ||
} | ||
|
||
} // namespace LazyCode | ||
#endif /* LAZYCODE_MAPRANGE_H_*/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#ifndef LAZYCODE_RANGEBASE_H_ | ||
#define LAZYCODE_RANGEBASE_H_ | ||
#include <utility> | ||
#include <iterator> | ||
#include <type_traits> | ||
|
||
namespace LazyCode { | ||
|
||
template <typename T> | ||
using RmRef = typename std::remove_reference<T>::type; | ||
|
||
template <typename T> | ||
using IsRef = typename std::is_same<RmRef<T>&, T>; | ||
|
||
struct RangeBase {}; | ||
|
||
template <typename T> | ||
using EnableIfRange = | ||
typename std::enable_if<std::is_base_of<RangeBase, RmRef<T>>::value, | ||
int>::type; | ||
|
||
template <typename T> | ||
using EnableIfNotRange = | ||
typename std::enable_if<!std::is_base_of<RangeBase, RmRef<T>>::value, | ||
int>::type; | ||
|
||
template <typename Iterator> | ||
class IterRange : public RangeBase { | ||
protected: | ||
Iterator first; | ||
Iterator last; | ||
|
||
public: | ||
IterRange(const Iterator& first, const Iterator& last) | ||
: first(first), last(last) {} | ||
|
||
inline Iterator begin() { return first; } | ||
inline Iterator end() { return last; } | ||
|
||
inline bool hasValue() { return first != last; } | ||
inline decltype(auto) getValue() { return *first; } | ||
inline void moveNext() { ++first; } | ||
}; | ||
|
||
template <typename Iterator> | ||
inline IterRange<Iterator> iterRange(const Iterator& first, | ||
const Iterator& last) { | ||
return IterRange<RmRef<Iterator>>(first, last); | ||
} | ||
|
||
template <typename Container> | ||
struct IterRangeWithContainer : public IterRange<typename Container::iterator> { | ||
typedef IterRange<typename Container::iterator> IterRangeBase; | ||
Container container; | ||
|
||
IterRangeWithContainer(Container& container) | ||
: IterRangeBase(std::begin(container), std::end(container)), | ||
container(std::move(container)) { | ||
// need to override first and last as container was moved | ||
IterRangeBase::first = std::begin(container); | ||
IterRangeBase::last = std::end(container); | ||
} | ||
}; | ||
|
||
template <typename Container> | ||
inline IterRangeWithContainer<Container> iterRangeWithBase( | ||
Container&& container) { | ||
return IterRangeWithContainer<RmRef<Container>>( | ||
std::forward<Container>(container)); | ||
} | ||
|
||
template <typename Container> | ||
inline IterRange<typename Container::iterator> toRange(Container& container) { | ||
return iterRange(std::begin(container), std::end(container)); | ||
} | ||
|
||
template <typename Container> | ||
inline IterRange<typename Container::iterator> toRange(Container&& container) { | ||
return iterRangeWithContainer(std::forward<Container>(container)); | ||
} | ||
|
||
template <typename Range> | ||
class RangeIterator : public std::iterator<std::input_iterator_tag, decltype(std::declval<Range>().getValue()), std::ptrdiff_t, void, void> { | ||
Range& range; | ||
|
||
public: | ||
RangeIterator(Range& range) : range(range) {} | ||
inline RangeIterator& operator++() { | ||
range.moveNext(); | ||
return *this; | ||
} | ||
inline decltype(auto) operator*() { return range.getValue(); } | ||
inline bool operator!=(const RangeIterator<Range>&) { | ||
return range.hasValue(); | ||
} | ||
}; | ||
|
||
} // namespace LazyCode | ||
#endif /*LAZYCODE_RANGEBASE_H_*/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
will be complete in a few days, worth the wait :) |