summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/poly_collection/test/function_types.hpp
blob: f8c154ff1c7236684ce258061254cc3c47ee5b55 (plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Copyright 2016-2018 Joaquin M Lopez Munoz.
 * 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)
 *
 * See http://www.boost.org/libs/poly_collection for library home page.
 */

#ifndef BOOST_POLY_COLLECTION_TEST_FUNCTION_TYPES_HPP
#define BOOST_POLY_COLLECTION_TEST_FUNCTION_TYPES_HPP

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/poly_collection/function_collection.hpp>
#include <typeinfo>

namespace function_types{

struct function1 final
{
  function1(int n):n{n}{}
  function1(function1&&)=default;
  function1(const function1&)=delete;
  function1& operator=(function1&&)=default;
  function1& operator=(const function1&)=delete;
  int operator()(int)const{return n;}
  friend bool operator==(
    const function1& x,const function1& y){return x.n==y.n;}
  int n;
};

struct function2
{
  function2(int n):n{n}{}
  int operator()(int x)const{return x*n;}
  bool operator==(const function2& x)const{return n==x.n;}
  int n;
};

struct function3
{
  function3():n{-1}{}
  function3(int n):n{n}{}
  int operator()(int x)const{return x*x*n;}
  int n;
};

struct function4:function3
{
  using function3::function3;
  int operator()(int x)const{return -(this->function3::operator()(x));}
  bool operator==(const function4& x)const{return n==x.n;}
};

struct function5
{
  function5(int n):n{n}{}
  int operator()(int x)const{return x*x*x*n;}
  int n;
};

struct int_alias /* brings this namespace into ADL for operator== below */
{
  int_alias(int n):n{n}{}
  operator int()const{return n;}
  int n;
};

using signature=int_alias(int);
using collection=boost::function_collection<signature>;

using t1=function1;
using t2=function2;
using t3=function3;
using t4=function4;
using t5=function5;

inline bool operator==(
  const collection::value_type& x,const collection::value_type& y)
{
  const std::type_info& xi=x.target_type();
  const std::type_info& yi=y.target_type();
  if(xi==yi){
    if(xi==typeid(t1))return (*x.target<t1>())==(*y.target<t1>());
    if(xi==typeid(t2))return (*x.target<t2>()).operator==(*y.target<t2>());
    if(xi==typeid(t4))return (*x.target<t4>()).operator==(*y.target<t4>());
  }
  return false;
}

inline bool operator==(const collection::value_type& x,const t1& y)
{
  const std::type_info& xi=x.target_type();
  if(xi==typeid(t1))return (*x.target<t1>())==y;
  return false;
}

inline bool operator==(const t1& x,const collection::value_type& y)
{
  return y==x;
}

inline bool operator==(const collection::value_type& x,const t2& y)
{
  const std::type_info& xi=x.target_type();
  if(xi==typeid(t2))return (*x.target<t2>())==y;
  return false;
}

inline bool operator==(const t2& x,const collection::value_type& y)
{
  return y==x;
}

inline bool operator==(const collection::value_type& x,const t4& y)
{
  const std::type_info& xi=x.target_type();
  if(xi==typeid(t4))return (*x.target<t4>())==y;
  return false;
}

inline bool operator==(const t4& x,const collection::value_type& y)
{
  return y==x;
}

inline bool operator==(const t1&,const t2&){return false;}
inline bool operator==(const t1&,const t4&){return false;}
inline bool operator==(const t2&,const t1&){return false;}
inline bool operator==(const t2&,const t4&){return false;}
inline bool operator==(const t4&,const t1&){return false;}
inline bool operator==(const t4&,const t2&){return false;}

struct to_int
{
  template<typename F>
  int operator()(const F& f)const{return f(1);}
};

} /* namespace function_types */

#endif