Blame view

3rdparty/boost_1_81_0/libs/hof/example/print.cpp 2.72 KB
73ef4ff3   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  /*=============================================================================
      Copyright (c) 2017 Paul Fultz II
      print.cpp
      Distributed under the Boost Software License, Version 1.0. (See accompanying
      file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  ==============================================================================*/
  /*=============================================================================
      Copyright (c) 2016 Paul Fultz II
      print.cpp
      Distributed under the Boost Software License, Version 1.0. (See accompanying
      file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  ==============================================================================*/
  
  #include "example.h"
  
  using namespace boost::hof;
  
  // ADL Lookup for ranges
  namespace adl {
  
  using std::begin;
  using std::end;
  
  template<class R>
  auto adl_begin(R&& r) BOOST_HOF_RETURNS(begin(r));
  template<class R>
  auto adl_end(R&& r) BOOST_HOF_RETURNS(end(r));
  }
  
  // Iterate over a tuple
  BOOST_HOF_STATIC_LAMBDA_FUNCTION(for_each_tuple) = [](const auto& sequence, auto f)
  {
      return unpack(proj(f))(sequence);
  };
  
  #ifdef _MSC_VER
  // On MSVC, trailing decltype doesn't work with generic lambdas, so seperate
  // functions can be used instead.
  template<class Self, class T>
  auto print_with_cout(Self, const T& x) -> decltype(std::cout << x, void())
  {
      std::cout << x << std::endl;
  }
  
  template<class Self, class T>
  auto print_with_range(Self self, const T& range) -> decltype(self(*adl::adl_begin(range)), void())
  {
      for(const auto& x:range) self(x);
  }
  
  template<class Self, class T>
  auto print_with_tuple(Self self, const T& tuple) -> decltype(for_each_tuple(tuple, self), void())
  {
      for_each_tuple(tuple, self);
  }
  
  // Recursively print everything
  BOOST_HOF_STATIC_FUNCTION(simple_print) = fix(first_of(
      BOOST_HOF_LIFT(print_with_cout),
      BOOST_HOF_LIFT(print_with_range),
      BOOST_HOF_LIFT(print_with_tuple)
  ));
  #else
  // Recursively print everything
  BOOST_HOF_STATIC_LAMBDA_FUNCTION(simple_print) = fix(first_of(
      [](auto, const auto& x) -> decltype(std::cout << x, void())
      {
          std::cout << x << std::endl;
      },
      [](auto self, const auto& range) -> decltype(self(*adl::adl_begin(range)), void())
      {
          for(const auto& x:range) self(x);
      },
      [](auto self, const auto& tuple) -> decltype(for_each_tuple(tuple, self), void())
      {
          for_each_tuple(tuple, self);
      }
  ));
  #endif
  
  // Make print function varidiac
  BOOST_HOF_STATIC_LAMBDA_FUNCTION(print) = proj(simple_print);
  
  int main()
  {
      print(5, "Hello world");
      print(5);
      std::vector<int> v = { 1, 2, 3, 4 };
      print(v);
  
      auto t = std::make_tuple(1, 2, 3, 4);
      print(t);
  
      auto m = std::make_tuple(3, v, t);
      print(m);
  }