Mirror reflection library - Lagoon run-time layer 0.5.13
|
00001 00010 #ifndef LAGOON_RANGE_ONLY_IF_1011291729_HPP 00011 #define LAGOON_RANGE_ONLY_IF_1011291729_HPP 00012 00013 #include <lagoon/range/utils.hpp> 00014 00015 LAGOON_NAMESPACE_BEGIN 00016 00017 namespace aux { 00018 00019 template <class Range, class Predicate> 00020 struct satisfying_predicate : public leaping_base 00021 { 00022 private: 00023 Range range; 00024 Predicate predicate; 00025 00026 // Skips those elements which do not satisfy the predicate 00027 void skip(void) 00028 { 00029 // while the range is not empty and the current element 00030 // does not satisfy the predicate step forward 00031 while(!range.empty() && !predicate(range.front())) 00032 range.step_front(); 00033 } 00034 public: 00035 satisfying_predicate(const satisfying_predicate& other) 00036 : range(other.range) 00037 , predicate(other.predicate) 00038 { 00039 skip(); 00040 } 00041 00042 satisfying_predicate(satisfying_predicate&& other) 00043 : range(std::move(other.range)) 00044 , predicate(std::move(other.predicate)) 00045 { 00046 skip(); 00047 } 00048 00049 satisfying_predicate(const Range& rng, const Predicate& pred) 00050 : range(rng) 00051 , predicate(pred) 00052 { 00053 skip(); 00054 } 00055 00056 satisfying_predicate(Range&& rng, Predicate&& pred) 00057 : range(std::forward(rng)) 00058 , predicate(std::forward(pred)) 00059 { 00060 skip(); 00061 } 00062 00063 inline bool empty(void) const 00064 { 00065 return range.empty(); 00066 } 00067 00068 void step_front(void) 00069 { 00070 range.step_front(); 00071 skip(); 00072 } 00073 00074 size_t leap_front(size_t leap) 00075 { 00076 return leaping_base::do_leap_front(*this, leap); 00077 } 00078 00079 inline auto front(void) const -> decltype(range.front()) 00080 { 00081 return range.front(); 00082 } 00083 00084 friend inline bool same_position( 00085 const satisfying_predicate& a, 00086 const satisfying_predicate& b 00087 ) 00088 { 00089 return same_position(a.range, b.range); 00090 } 00091 }; 00092 00093 } // namespace aux 00094 00095 #ifdef MIRROR_DOCUMENTATION_ONLY 00096 00097 00105 template <class Range, typename Predicate> 00106 UnspecifiedRange only_if(Range range, Predicate predicate); 00107 #else 00108 template <class Range, typename Predicate> 00109 inline aux::satisfying_predicate<Range, Predicate> 00110 only_if(Range range, Predicate predicate) 00111 { 00112 return aux::satisfying_predicate<Range, Predicate>(range, predicate); 00113 } 00114 #endif 00115 00116 LAGOON_NAMESPACE_END 00117 00118 #endif //include guard 00119