fork(1) download
  1. #include <algorithm>
  2. #include <iterator>
  3. #include <utility>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <list>
  8.  
  9. #include <cctype>
  10.  
  11. namespace pl
  12. {
  13. namespace detail
  14. {
  15. template <typename Lambda>
  16. struct lambda_result_helper;
  17.  
  18. template <typename Result, typename Class, typename... Arg>
  19. struct lambda_result_helper < Result(Class::*)(Arg...) const >
  20. {
  21. typedef Result type;
  22. };
  23.  
  24. template <typename Lambda>
  25. struct lambda_result
  26. {
  27. typedef typename lambda_result_helper < decltype(&Lambda::operator()) >::type type;
  28. };
  29.  
  30. template <typename Functor, typename Iterator>
  31. class grep_iterator
  32. {
  33. public:
  34. typedef typename Iterator::value_type source_type;
  35. typedef typename Iterator::difference_type difference_type;
  36. typedef source_type value_type;
  37. typedef value_type const & reference;
  38. typedef value_type const * pointer;
  39. typedef std::forward_iterator_tag iterator_category;
  40.  
  41. grep_iterator(Functor f, Iterator it, Iterator end)
  42. : m_f(f)
  43. , m_it(it)
  44. , m_end(end)
  45. {
  46. while (m_it != m_end && !m_f(*m_it))
  47. ++m_it;
  48. }
  49.  
  50. grep_iterator(grep_iterator const & source)
  51. : m_f(source.m_f)
  52. , m_it(source.m_it)
  53. , m_end(source.m_end)
  54. {
  55. }
  56.  
  57. grep_iterator & operator = (grep_iterator const & source)
  58. {
  59. m_f = source.m_f;
  60. m_it = source.m_it;
  61. m_end = source.m_end;
  62. return *this;
  63. }
  64.  
  65. grep_iterator & operator ++ ()
  66. {
  67. if (m_it == m_end)
  68. return *this;
  69.  
  70. do
  71. {
  72. ++m_it;
  73. } while (m_it != m_end && !m_f(*m_it));
  74. return *this;
  75. }
  76.  
  77. grep_iterator operator ++ (int)
  78. {
  79. if (m_it == m_end)
  80. return *this;
  81.  
  82. grep_iterator old(*this);
  83.  
  84. do
  85. {
  86. ++m_it;
  87. } while (m_it != m_end && !m_f(*m_it));
  88.  
  89. return old;
  90. }
  91.  
  92. bool operator == (grep_iterator const & other) const
  93. {
  94. return m_it == other.m_it;
  95. }
  96.  
  97. bool operator != (grep_iterator const & other) const
  98. {
  99. return m_it != other.m_it;
  100. }
  101.  
  102. reference operator * () const
  103. {
  104. return *m_it;
  105. }
  106.  
  107. pointer operator -> () const
  108. {
  109. return &(*m_it);
  110. }
  111.  
  112. private:
  113. Functor m_f;
  114. Iterator m_it;
  115. Iterator m_end;
  116. };
  117.  
  118. template <typename Functor, typename SContainer>
  119. class grep_proxy
  120. {
  121. public:
  122. typedef typename SContainer::const_iterator source_iterator;
  123.  
  124. grep_proxy(Functor f, SContainer const & c)
  125. : m_f(f)
  126. , m_c(c)
  127. {
  128. }
  129.  
  130. template <typename TContainer>
  131. operator TContainer () const
  132. {
  133. return to<TContainer>();
  134. }
  135.  
  136. template <typename TContainer>
  137. TContainer to() const
  138. {
  139. TContainer c;
  140. std::copy_if(std::begin(m_c), std::end(m_c), std::inserter(c, std::end(c)), m_f);
  141. return c;
  142. }
  143.  
  144.  
  145. grep_iterator<Functor, source_iterator> begin() const
  146. {
  147. return grep_iterator<Functor, source_iterator>(m_f, std::begin(m_c), std::end(m_c));
  148. }
  149.  
  150. grep_iterator<Functor, source_iterator> end() const
  151. {
  152. return grep_iterator<Functor, source_iterator>(m_f, std::end(m_c), std::end(m_c));
  153. }
  154.  
  155. private:
  156. Functor m_f;
  157. SContainer const & m_c;
  158. };
  159.  
  160. template <typename Functor, typename Iterator>
  161. class map_iterator
  162. {
  163. public:
  164. typedef typename Iterator::value_type source_type;
  165. typedef typename Iterator::difference_type difference_type;
  166. typedef typename lambda_result<Functor>::type value_type;
  167. typedef value_type const & reference;
  168. typedef value_type const * pointer;
  169. typedef std::forward_iterator_tag iterator_category;
  170.  
  171. map_iterator(Functor f, Iterator it)
  172. : m_f(f)
  173. , m_it(it)
  174. {
  175. }
  176.  
  177. map_iterator(map_iterator const & source)
  178. : m_f(source.m_f)
  179. , m_it(source.m_it)
  180. {
  181. }
  182.  
  183. map_iterator & operator = (map_iterator const & source)
  184. {
  185. m_f = source.m_f;
  186. m_it = source.m_it;
  187. return *this;
  188. }
  189.  
  190. map_iterator & operator ++ ()
  191. {
  192. ++m_it;
  193. return *this;
  194. }
  195.  
  196. map_iterator operator ++ (int)
  197. {
  198. map_iterator old(*this);
  199. ++m_it;
  200. return old;
  201. }
  202.  
  203. bool operator == (map_iterator const & other) const
  204. {
  205. return m_it == other.m_it;
  206. }
  207.  
  208. bool operator != (map_iterator const & other) const
  209. {
  210. return m_it != other.m_it;
  211. }
  212.  
  213. reference operator * () const
  214. {
  215. m_val = m_f(*m_it);
  216. return m_val;
  217. }
  218.  
  219. pointer operator -> () const
  220. {
  221. m_val = m_f(*m_it);
  222. return &m_val;
  223. }
  224.  
  225. private:
  226. Functor m_f;
  227. Iterator m_it;
  228. mutable value_type m_val;
  229. };
  230.  
  231. template <typename Functor, typename SContainer>
  232. class map_proxy
  233. {
  234. public:
  235. typedef typename SContainer::const_iterator source_iterator;
  236.  
  237. map_proxy(Functor f, SContainer const & c)
  238. : m_f(f)
  239. , m_c(c)
  240. {
  241. }
  242.  
  243. template <typename TContainer>
  244. operator TContainer () const
  245. {
  246. return to<TContainer>();
  247. }
  248.  
  249. template <typename TContainer>
  250. TContainer to() const
  251. {
  252. TContainer c;
  253. std::transform(std::begin(m_c), std::end(m_c), std::inserter(c, std::end(c)), m_f);
  254. return c;
  255. }
  256.  
  257. map_iterator<Functor, source_iterator> begin() const
  258. {
  259. return map_iterator<Functor, source_iterator>(m_f, std::begin(m_c));
  260. }
  261.  
  262. map_iterator<Functor, source_iterator> end() const
  263. {
  264. return map_iterator<Functor, source_iterator>(m_f, std::end(m_c));
  265. }
  266.  
  267. private:
  268. Functor m_f;
  269. SContainer const & m_c;
  270. };
  271. }
  272.  
  273. template <typename Functor, typename Container>
  274. detail::grep_proxy<Functor, Container> grep(Functor f, Container const & c)
  275. {
  276. return detail::grep_proxy<Functor, Container>(f, c);
  277. }
  278.  
  279. template <typename Functor, typename Container>
  280. detail::map_proxy<Functor, Container> map(Functor f, Container const & c)
  281. {
  282. return detail::map_proxy<Functor, Container>(f, c);
  283. }
  284. }
  285.  
  286.  
  287. int main()
  288. {
  289. using pl::map;
  290. using pl::grep;
  291.  
  292. std::string hello = "Hello world!";
  293. std::string caps = map([](char c) { return std::toupper(c); }, hello).to<std::string>();
  294.  
  295. std::cout << caps << std::endl;
  296.  
  297. std::vector<double> numbers = { 0.3, 0.4, 0.5, 0.6, 0.7 };
  298. for (auto && n : map([](double d) { return static_cast<int>(d * 2.0 + 1) / 2; }, numbers))
  299. std::cout << n << std::endl;
  300.  
  301. std::string lower = grep([](char c) { return std::islower(c); }, hello).to<std::string>();
  302. std::cout << lower << std::endl;
  303.  
  304. for (auto && n : grep([](double d) { return d > 0.5; }, numbers))
  305. std::cout << n << std::endl;
  306.  
  307. std::cin.get();
  308.  
  309. return 0;
  310. }
  311.  
Success #stdin #stdout 0s 3436KB
stdin
Standard input is empty
stdout
HELLO WORLD!
0
0
1
1
1
elloworld
0.6
0.7