Guest User

Untitled

a guest
Jun 20th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.41 KB | None | 0 0
  1. //
  2. // 困ったちゃん binder 兄弟を boost::result_of を使って少しはマシにしよう計画
  3. //
  4. #ifndef ETUDE_INCLUDED_BINDERS_HPP_
  5. #define ETUDE_INCLUDED_BINDERS_HPP_
  6.  
  7. #include <boost/compressed_pair.hpp>
  8. #include <boost/utility/result_of.hpp>
  9. #include <boost/type_traits/add_reference.hpp>
  10.  
  11. namespace etude {
  12.  
  13. // 困ったちゃん1号
  14. template<class Fn, class T = typename Fn::first_argument_type>
  15. class binder1st
  16. : boost::compressed_pair<Fn, T>
  17. {
  18. typedef boost::compressed_pair<Fn, T> base;
  19. using base::first; using base::second;
  20. typedef typename boost::add_reference<T const>::type param_type;
  21.  
  22. public:
  23. binder1st( Fn f, param_type x )
  24. : base( f, x ) {}
  25.  
  26. template<class Signature>
  27. struct result;
  28. template<class F_, class U>
  29. struct result<F_(U)>
  30. : boost::result_of<Fn(T, U)> {};
  31.  
  32. template<class U>
  33. typename boost::result_of<Fn(T, U)>::type operator()( U const& y ) {
  34. return first()( second(), y );
  35. }
  36. template<class U>
  37. typename boost::result_of<Fn(T, U)>::type operator()( U const& y ) const {
  38. return first()( second(), y );
  39. }
  40.  
  41. };
  42.  
  43. // 困ったちゃん2号
  44. template<class Fn, class U = typename Fn::second_argument_type>
  45. class binder2nd
  46. : boost::compressed_pair<Fn, U>
  47. {
  48. typedef boost::compressed_pair<Fn, U> base;
  49. using base::first; using base::second;
  50. typedef typename boost::add_reference<U const>::type param_type;
  51.  
  52. public:
  53. binder2nd( Fn f, param_type y )
  54. : base( f, y ) {}
  55.  
  56. template<class Signature>
  57. struct result;
  58. template<class F_, class T>
  59. struct result<F_(T)>
  60. : boost::result_of<Fn(T, U)> {};
  61.  
  62. template<class T>
  63. typename boost::result_of<Fn(T, U)>::type operator()( T const& x ) {
  64. return first()( x, second() );
  65. }
  66. template<class T>
  67. typename boost::result_of<Fn(T, U)>::type operator()( T const& x ) const {
  68. return first()( x, second() );
  69. }
  70.  
  71. };
  72.  
  73. // ヘルパ関数
  74. // T, U が先なのは、参照キャプチャしたい時に
  75. // bind1st<hoge&>( f, x ) って書けるようにするため。
  76. template<class T, class Fn>
  77. inline binder1st<Fn, T> bind1st( Fn f, T x ) {
  78. return binder1st<Fn, T>( f, x );
  79. }
  80. template<class U, class Fn>
  81. inline binder2nd<Fn, U> bind2nd( Fn f, U y ) {
  82. return binder2nd<Fn, U>( f, y );
  83. }
  84.  
  85. } // namespace etude
  86.  
  87. #endif // #ifndef ETUDE_INCLUDED_BINDERS_HPP_
Add Comment
Please, Sign In to add comment