mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
WIP
git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@395 f6dd340e-d3f9-0310-b409-bdd246841980
This commit is contained in:
parent
75866d2f7b
commit
e312a9f415
3 changed files with 341 additions and 66 deletions
|
@ -87,7 +87,7 @@ situations where bound friends are useful:
|
|||
class A
|
||||
{ // fun() is used as friend bound to A,
|
||||
// instantiated for X, whatever X may be
|
||||
friend void fun<A<X> >(A<X> *);
|
||||
friend void fun<A<X>>(A<X> *);
|
||||
|
||||
public:
|
||||
A();
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
template <typename Key, typename Value>
|
||||
class Dictionary
|
||||
{
|
||||
friend Dictionary<Key, Value> subset<Key, Value>
|
||||
(Key const &key, Dictionary<Key, Value> const &dict);
|
||||
friend Dictionary<Key, Value>
|
||||
subset<Key, Value>(Key const &key,
|
||||
Dictionary<Key, Value> const &dict);
|
||||
|
||||
std::map<Key, Value> d_dict;
|
||||
public:
|
||||
Dictionary();
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// The Aux struct receives
|
||||
// 1. an index that reduces to zero initially representing the number of
|
||||
// elements in a tuple (int t_size);
|
||||
// 2. the tuple itself (tuple, typename Tuple)
|
||||
// 3. the address of the function to call (fun, typename Fun)
|
||||
// 4. the first argument to the function (received from the wrapper's
|
||||
// function call operator (arg, typename ArgType))
|
||||
// function call operator (arg, typename Arg1))
|
||||
// 5. Any other series of arguments (params, typename ... Params)
|
||||
|
||||
namespace FBB
|
||||
|
@ -18,56 +21,169 @@ namespace FBB
|
|||
namespace IUO
|
||||
{
|
||||
|
||||
// ======================================================
|
||||
|
||||
// Wrap1<size, ... degenerates to Wrap1<0, .... Wrap1<0 calls the unary
|
||||
// function, receiving its initial argument from the STL algorithm and
|
||||
// optional other arguments from Wrap1 itself
|
||||
//
|
||||
|
||||
template < int size,
|
||||
typename Tuple,
|
||||
typename Fun,
|
||||
typename ArgType,
|
||||
typename ... Params>
|
||||
struct Wrap
|
||||
typename Return, typename Tuple,
|
||||
typename Fun, typename Arg1, typename ... Params>
|
||||
struct Wrap1
|
||||
{
|
||||
typedef typename std::tuple_element<size - 1, Tuple>::type ElType;
|
||||
|
||||
inline Wrap(Tuple &&tuple, Fun fun, ArgType &&arg, Params && ... params)
|
||||
inline Wrap1(Return &ret,
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg, Params && ... params)
|
||||
{
|
||||
Wrap<size - 1, Tuple, Fun, ArgType, ElType, Params ...>
|
||||
Wrap1<size - 1, Return, Tuple, Fun, Arg1, ElType, Params ...>
|
||||
(
|
||||
ret,
|
||||
std::forward<Tuple>(tuple),
|
||||
fun,
|
||||
std::forward<ArgType>(arg),
|
||||
std::forward<Arg1>(arg),
|
||||
std::forward<ElType>(std::get<size - 1>(tuple)),
|
||||
std::forward<Params>(params) ...);
|
||||
std::forward<Params>(params) ...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// When the index has reduced to 0 the function is called, receiving arg and
|
||||
// all params parameters.
|
||||
|
||||
template <
|
||||
typename Tuple,
|
||||
typename Fun,
|
||||
typename ArgType,
|
||||
typename ... Params>
|
||||
struct Wrap<0, Tuple, Fun, ArgType, Params ...>
|
||||
template < typename Return, typename Tuple,
|
||||
typename Fun, typename Arg1, typename ... Params>
|
||||
struct Wrap1<0, Return, Tuple, Fun, Arg1, Params ...>
|
||||
{
|
||||
inline Wrap(Tuple &&tuple, Fun fun, ArgType &&arg, Params && ... params)
|
||||
inline Wrap1(Return &ret,
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg, Params && ... params)
|
||||
{
|
||||
fun(std::forward<ArgType>(arg), std::forward<Params>(params) ...);
|
||||
ret =
|
||||
fun(std::forward<Arg1>(arg), std::forward<Params>(params) ...);
|
||||
}
|
||||
};
|
||||
|
||||
template < int size, typename Tuple,
|
||||
typename Fun, typename Arg1, typename ... Params>
|
||||
struct Wrap1<size, void, Tuple, Fun, Arg1, Params ...>
|
||||
{
|
||||
typedef typename std::tuple_element<size - 1, Tuple>::type ElType;
|
||||
|
||||
inline Wrap1(Tuple &&tuple, Fun fun, Arg1 &&arg, Params && ... params)
|
||||
{
|
||||
Wrap1<size - 1, void, Tuple, Fun, Arg1, ElType, Params ...>
|
||||
(
|
||||
std::forward<Tuple>(tuple),
|
||||
fun,
|
||||
std::forward<Arg1>(arg),
|
||||
std::forward<ElType>(std::get<size - 1>(tuple)),
|
||||
std::forward<Params>(params) ...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template < typename Tuple,
|
||||
typename Fun, typename Arg1, typename ... Params>
|
||||
struct Wrap1<0, void, Tuple, Fun, Arg1, Params ...>
|
||||
{
|
||||
inline Wrap1(Tuple &&tuple, Fun fun, Arg1 &&arg, Params && ... params)
|
||||
{
|
||||
fun(std::forward<Arg1>(arg), std::forward<Params>(params) ...);
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
template < int size,
|
||||
typename Return, typename Tuple,
|
||||
typename Fun, typename Arg1, typename Arg2, typename ... Params>
|
||||
struct Wrap2
|
||||
{
|
||||
typedef typename std::tuple_element<size - 1, Tuple>::type ElType;
|
||||
|
||||
inline Wrap2(Return &ret,
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg1, Arg2 &&arg2,
|
||||
Params && ... params)
|
||||
{
|
||||
Wrap2<size - 1, Return, Tuple, Fun, Arg1, Arg2, ElType, Params ...>
|
||||
(
|
||||
ret,
|
||||
std::forward<Tuple>(tuple),
|
||||
fun,
|
||||
std::forward<Arg1>(arg1),
|
||||
std::forward<Arg2>(arg2),
|
||||
std::forward<ElType>(std::get<size - 1>(tuple)),
|
||||
std::forward<Params>(params) ...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template < typename Return, typename Tuple,
|
||||
typename Fun, typename Arg1, typename Arg2, typename ... Params>
|
||||
struct Wrap2<0, Return, Tuple, Fun, Arg1, Arg2, Params ...>
|
||||
{
|
||||
inline Wrap2(Return &ret,
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg1, Arg2 &&arg2,
|
||||
Params && ... params)
|
||||
{
|
||||
ret =
|
||||
fun(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
|
||||
std::forward<Params>(params) ...);
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
template < int size,
|
||||
typename Tuple,
|
||||
typename Fun, typename Arg1, typename Arg2, typename ... Params>
|
||||
struct Wrap2<size, void, Tuple, Fun, Arg1, Arg2, Params ...>
|
||||
{
|
||||
typedef typename std::tuple_element<size - 1, Tuple>::type ElType;
|
||||
|
||||
inline Wrap2(
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg1, Arg2 &&arg2,
|
||||
Params && ... params)
|
||||
{
|
||||
Wrap2<size - 1, void, Tuple, Fun, Arg1, Arg2, ElType, Params ...>
|
||||
(
|
||||
std::forward<Tuple>(tuple),
|
||||
fun,
|
||||
std::forward<Arg1>(arg1),
|
||||
std::forward<Arg2>(arg2),
|
||||
std::forward<ElType>(std::get<size - 1>(tuple)),
|
||||
std::forward<Params>(params) ...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
typename Tuple,
|
||||
typename Fun, typename Arg1, typename Arg2, typename ... Params>
|
||||
struct Wrap2<0, void, Tuple, Fun, Arg1, Arg2, Params ...>
|
||||
{
|
||||
inline Wrap2(
|
||||
Tuple &&tuple, Fun fun, Arg1 &&arg1, Arg2 &&arg2,
|
||||
Params && ... params)
|
||||
{
|
||||
fun(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
|
||||
std::forward<Params>(params) ...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
struct RetType;
|
||||
|
||||
template <typename Ret, typename ... Par>
|
||||
struct RetType<Ret (*)(Par ...)>
|
||||
{
|
||||
typedef Ret type;
|
||||
};
|
||||
|
||||
} // IUO
|
||||
|
||||
template <typename Fun, typename ... Params>
|
||||
template <int unary, typename Return, typename Fun, typename ... Params>
|
||||
class Wrap
|
||||
{
|
||||
template < int size,
|
||||
typename Tuple,
|
||||
typename Fn,
|
||||
typename ArgType,
|
||||
typename ... Parms>
|
||||
friend struct IUO::Wrap;
|
||||
|
||||
Fun d_fun;
|
||||
std::tuple<Params ...> d_tuple;
|
||||
|
||||
|
@ -78,71 +194,228 @@ class Wrap
|
|||
d_tuple(std::forward<Params>(params) ...)
|
||||
{}
|
||||
|
||||
template <typename ArgType>
|
||||
void operator()(ArgType &¶m)
|
||||
template <typename Arg1>
|
||||
Return operator()(Arg1 &&arg1)
|
||||
{
|
||||
IUO::Wrap<std::tuple_size<std::tuple<Params ...>>::value,
|
||||
Return ret;
|
||||
IUO::Wrap1<
|
||||
std::tuple_size<std::tuple<Params ...>>::value,
|
||||
Return &,
|
||||
std::tuple<Params ...>,
|
||||
Fun,
|
||||
ArgType
|
||||
Arg1
|
||||
>
|
||||
(d_tuple, d_fun, param);
|
||||
(ret, d_tuple, d_fun, arg1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <int unary, typename Fun, typename ... Params>
|
||||
class Wrap<unary, void, Fun, Params ...>
|
||||
{
|
||||
Fun d_fun;
|
||||
std::tuple<Params ...> d_tuple;
|
||||
|
||||
public:
|
||||
Wrap(Fun fun, Params && ... params)
|
||||
:
|
||||
d_fun(fun),
|
||||
d_tuple(std::forward<Params>(params) ...)
|
||||
{}
|
||||
|
||||
template <typename Arg1>
|
||||
void operator()(Arg1 &&arg1)
|
||||
{
|
||||
IUO::Wrap1<
|
||||
std::tuple_size<std::tuple<Params ...>>::value,
|
||||
void,
|
||||
std::tuple<Params ...>,
|
||||
Fun,
|
||||
Arg1
|
||||
>
|
||||
(d_tuple, d_fun, arg1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ====================================================================
|
||||
|
||||
template <typename Return, typename Fun, typename ... Params>
|
||||
class Wrap<2, Return, Fun, Params ...>
|
||||
{
|
||||
Fun d_fun;
|
||||
std::tuple<Params ...> d_tuple;
|
||||
|
||||
public:
|
||||
Wrap(Fun fun, Params && ... params)
|
||||
:
|
||||
d_fun(fun),
|
||||
d_tuple(std::forward<Params>(params) ...)
|
||||
{}
|
||||
|
||||
template <typename Arg1, typename Arg2>
|
||||
Return operator()(Arg1 &&arg1, Arg2 &&arg2)
|
||||
{
|
||||
Return ret;
|
||||
IUO::Wrap2<
|
||||
std::tuple_size<std::tuple<Params ...>>::value,
|
||||
Return &,
|
||||
std::tuple<Params ...>,
|
||||
Fun,
|
||||
Arg1,
|
||||
Arg2
|
||||
>
|
||||
(ret, d_tuple, d_fun, arg1, arg2);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Fun, typename ... Params>
|
||||
class Wrap<2, void, Fun, Params ...>
|
||||
{
|
||||
Fun d_fun;
|
||||
std::tuple<Params ...> d_tuple;
|
||||
|
||||
public:
|
||||
Wrap(Fun fun, Params && ... params)
|
||||
:
|
||||
d_fun(fun),
|
||||
d_tuple(std::forward<Params>(params) ...)
|
||||
{}
|
||||
|
||||
template <typename Arg1>
|
||||
void operator()(Arg1 &&arg1)
|
||||
{
|
||||
IUO::Wrap1<
|
||||
std::tuple_size<std::tuple<Params ...>>::value,
|
||||
void,
|
||||
std::tuple<Params ...>,
|
||||
Fun,
|
||||
Arg1
|
||||
>
|
||||
(d_tuple, d_fun, arg1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ============================================================
|
||||
|
||||
struct Wrapper
|
||||
{
|
||||
template <typename Func, typename ... Param>
|
||||
static Wrap<Func, Param ...>
|
||||
gen(Func fun, Param && ... param)
|
||||
static Wrap<1,
|
||||
typename IUO::RetType<Func>::type /*Return*/,
|
||||
Func, Param ...>
|
||||
unary(Func fun, Param && ... param)
|
||||
{
|
||||
Wrap<Func, Param ...>
|
||||
ret(fun, std::forward<Param>(param) ... );
|
||||
return ret;
|
||||
Wrap<1,
|
||||
typename IUO::RetType<Func>::type /*Return*/,
|
||||
Func, Param ...>
|
||||
wrap(fun, std::forward<Param>(param) ... );
|
||||
return wrap;
|
||||
}
|
||||
|
||||
template <typename Func, typename ... Param>
|
||||
static Wrap<2,
|
||||
typename IUO::RetType<Func>::type /*Return*/,
|
||||
Func, Param ...>
|
||||
binary(Func fun, Param && ... param)
|
||||
{
|
||||
Wrap<2,
|
||||
typename IUO::RetType<Func>::type /*Return*/,
|
||||
Func, Param ...>
|
||||
wrap(fun, std::forward<Param>(param) ... );
|
||||
return wrap;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // FBB
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace FBB;
|
||||
|
||||
class Vector
|
||||
class Strings
|
||||
{
|
||||
vector<int> d_v;
|
||||
vector<string> d_vs;
|
||||
|
||||
public:
|
||||
Strings()
|
||||
:
|
||||
d_vs({"one", "two", "", "three"})
|
||||
{}
|
||||
|
||||
Vector()
|
||||
:
|
||||
d_v({1, 2, 3, 4})
|
||||
{}
|
||||
void display(ostream &out) const
|
||||
{
|
||||
size_t nr = 1;
|
||||
find_if(d_vs.begin(), d_vs.end(),
|
||||
Wrapper::unary(untilEmpty, nr, out));
|
||||
}
|
||||
|
||||
void run(ostream &out)
|
||||
{
|
||||
int count = 0;
|
||||
for_each(d_v.begin(), d_v.end(),
|
||||
Wrapper::gen(callfun, count, out));
|
||||
cout << "Number of calls: " << count << '\n';
|
||||
}
|
||||
void display() const
|
||||
{
|
||||
for_each(d_vs.begin(), d_vs.end(),
|
||||
Wrapper::unary(toCout));
|
||||
}
|
||||
|
||||
private:
|
||||
void show(ostream &out) const
|
||||
{
|
||||
size_t nr = 1;
|
||||
for_each(d_vs.begin(), d_vs.end(),
|
||||
Wrapper::unary(all, nr, out));
|
||||
}
|
||||
|
||||
static void callfun(int v, int &count, ostream &o)
|
||||
{
|
||||
o << "Value is: " << v << '\n';
|
||||
++count;
|
||||
}
|
||||
void accu(ostream &out) const
|
||||
{
|
||||
size_t nr = 1;
|
||||
equal(d_vs.begin(), d_vs.end(), d_vs.rbegin(),
|
||||
Wrapper::binary(cmpfun2, nr, out));
|
||||
}
|
||||
|
||||
private:
|
||||
static bool cmpfun2(string const &str1, string const &str2,
|
||||
size_t &nr, ostream &out)
|
||||
{
|
||||
out << nr++ << " " << str1 << " and " << str2 << '\n';
|
||||
return true; // don't stop
|
||||
}
|
||||
|
||||
static void toCout(string const &str)
|
||||
{
|
||||
cout << "toCout: " << str << '\n';
|
||||
}
|
||||
|
||||
static bool untilEmpty(string const &str, size_t &nr, ostream &out)
|
||||
{
|
||||
if (str.empty())
|
||||
return true; // stop
|
||||
|
||||
out << nr++ << " " << str << '\n';
|
||||
return false; // don't stop
|
||||
}
|
||||
static void all(string const &str, size_t &nr, ostream &out)
|
||||
{
|
||||
out << nr++ << " " << str << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Vector v;
|
||||
v.run(cout);
|
||||
Strings s;
|
||||
|
||||
s.display(cout);
|
||||
cout << "========\n";
|
||||
s.display();
|
||||
cout << "========\n";
|
||||
s.show(cout);
|
||||
cout << "========\n";
|
||||
s.accu(cout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue