forked from ChaiScript/ChaiScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbind_first.hpp
More file actions
85 lines (67 loc) · 2.46 KB
/
Copy pathbind_first.hpp
File metadata and controls
85 lines (67 loc) · 2.46 KB
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
// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// Copyright 2009-2018, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#ifndef CHAISCRIPT_BIND_FIRST_HPP_
#define CHAISCRIPT_BIND_FIRST_HPP_
#include <functional>
namespace chaiscript
{
namespace detail
{
template<typename T>
constexpr T* get_pointer(T *t) noexcept
{
return t;
}
template<typename T>
T* get_pointer(const std::reference_wrapper<T> &t) noexcept
{
return &t.get();
}
template<typename O, typename Ret, typename P1, typename ... Param>
constexpr auto bind_first(Ret (*f)(P1, Param...), O&& o)
{
return [f, o = std::forward<O>(o)](Param...param) -> Ret {
return f(o, std::forward<Param>(param)...);
};
}
template<typename O, typename Ret, typename Class, typename ... Param>
constexpr auto bind_first(Ret (Class::*f)(Param...), O&& o)
{
return [f, o = std::forward<O>(o)](Param...param) -> Ret {
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
};
}
template<typename O, typename Ret, typename Class, typename ... Param>
constexpr auto bind_first(Ret (Class::*f)(Param...) const, O&& o)
{
return [f, o = std::forward<O>(o)](Param...param) -> Ret {
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
};
}
template<typename O, typename Ret, typename P1, typename ... Param>
auto bind_first(const std::function<Ret (P1, Param...)> &f, O&& o)
{
return [f, o = std::forward<O>(o)](Param...param) -> Ret {
return f(o, std::forward<Param>(param)...);
};
}
template<typename F, typename O, typename Ret, typename Class, typename P1, typename ... Param>
constexpr auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const)
{
return [fo, o = std::forward<O>(o), f](Param ...param) -> Ret {
return (fo.*f)(o, std::forward<Param>(param)...);
};
}
template<typename F, typename O>
constexpr auto bind_first(const F &f, O&& o)
{
return bind_first(f, std::forward<O>(o), &F::operator());
}
}
}
#endif