Using operator new as a functor/function pointer - c++11

In C++11, let's say I have a function that takes a functor/function and it forwards the arguments to that function. I can pass in a pointer to std::make_shared, which causes it to instantiate a class and call its contructor. But what is the equivalent to doing this with a raw operator new instead? It seems like std::allocator is what I should use, but the construct function there requires a pointer to the allocated memory. I can make it work by wrapping the new call into the template function new_object, but it seems like there should be a way for me to retrieve that function pointer directly.
This is what I have so far:
#include <iostream>
#include <memory>
struct foo
{
foo(int i, const std::string& s)
{
std::cout << "i = " << i << " s = " << s << std::endl;
}
};
template <typename F, typename... Args>
void do_something(F f, Args&&... args)
{
f(std::forward<Args>(args)...);
}
// Is there a way to avoid this wrapper and handing a function pointer to
// something like ::new<foo, int, std::string> directly? Similar to std::make_shared<foo>?
template <typename C, typename... Args>
C* new_object(Args&&... args)
{
return new C(std::forward<Args>(args)...);
}
int main()
{
do_something(std::make_shared<foo, int, std::string>, 1, "test1"); // This works
do_something(new_object<foo, int, std::string>, 12, "test2");
return 0;
}

Why not something like this?
std::allocator<foo> alloc;
do_something(std::bind(&std::allocator<foo>::construct<foo, int, std::string>, &alloc, alloc.allocate(sizeof(foo)), std::placeholders::_1, std::placeholders::_2), 12, "test2");

Related

How can I "generate" template spezialations for a function from a variadic template argument?

I think I will first show the example and then explain it:
#include <array>
template<typename T_, size_t size_>
struct arg
{
using T = T_;
static constexpr size_t size = size_;
};
template<typename... Arugments>
struct Foo
{
template<typename Argument>
std::array<typename Argument::T, Argument::size>& getArray() // specializations of all args in Arguments should be generated
{
static std::array<typename Argument::T, Argument::size> arr;
return arr;
}
};
int main()
{
Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo;
myFoo.getArray<arg<int, 10>>();
myFoo.getArray<arg<float, 10>>(); // should return a different array than the line above
myFoo.getArray<arg<bool, 1>>(); // should NOT work because arg<bool, 10> is was not passed to Foo
}
If got a struct arg which contains the information how to construct arr in getArray. A list of args is passed to Foo. Now I want that template specializations of getArray to be generated for each arg in Arguments. If no specialization was generated for a specific arg I want that some kind of error occurs.
How could I achieve this?
You can use static_assert to make sure Argument is part of Arguments with a helper struct.
#include <array>
#include <iostream>
template <typename... T>
struct contains;
template <typename T>
struct contains<T> : std::false_type {};
template <typename T, typename U, typename... Rest>
struct contains<T, U, Rest...> : contains<T, Rest...> {};
template <typename T, typename... Rest>
struct contains<T, T, Rest...> : std::true_type {};
template<typename T_, std::size_t size_>
struct arg
{
using T = T_;
static constexpr std::size_t size = size_;
};
template<typename... Arguments>
struct Foo
{
template<typename Argument>
std::array<typename Argument::T, Argument::size>& getArray() // specializations of all args in Arguments should be generated
{
static_assert(contains<Argument, Arguments...>(), "Invalid type");
static std::array<typename Argument::T, Argument::size> arr;
return arr;
}
};
int main()
{
Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo;
myFoo.getArray<arg<int, 10>>()[5] = 7;
myFoo.getArray<arg<float, 10>>(); // should return a different array than the line above
//myFoo.getArray<arg<bool, 1>>(); // should NOT work because arg<bool, 10> is was not passed to Foo
Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo2;
std::cout << myFoo2.getArray<arg<int, 10>>()[5];
Foo<arg<int, 10>, arg<float, 10>, arg<double, 1>> myFoo3;
std::cout << myFoo3.getArray<arg<int, 10>>()[5];
}
Just wanted to also point out that as demonstrated by the code, myFoo and myFoo2 returns the same array since they are the exact same type.
myFoo3 on the other hand is a separate type, which means the getArray member function is a separate function and has it's own copy of the same type array.

Identify pointers in a tuple c++11

I need to convert a tuple to a byte array. This is the code I use to convert to byte array:
template< typename T > std::array< byte, sizeof(T) > get_bytes( const T& multiKeys )
{
std::array< byte, sizeof(T) > byteArr ;
const byte* start = reinterpret_cast< const byte* >(std::addressof(multiKeys) ) ;
const byte* end = start + sizeof(T);
std::copy(start, end, std::begin(byteArr));
return byteArr;
}
Here is how I call it:
void foo(T... keyTypes){
keys = std::tuple<T... >(keyTypes...);
const auto bytes = get_bytes(keys);
}
I need to augment this code such that when a pointer is a part of the tuple, I dereference it to it's value and then pass the new tuple, without any pointers, to the get_bytes() function. How do I detect the presence of a pointer in the tuple? I can then iterate through the tuple and dereference it with:
std::cout << *std::get<2>(keys) << std::endl;
Add a trivial overload: T get_bytes(T const* t) { return getBytes(*t); }.
That would be easy with C++14 :
#include <iostream>
#include <tuple>
#include <utility>
template <class T> decltype(auto) get_dereferenced_value(T &&value) {
return std::forward<T>(value);
}
template <class T> decltype(auto) get_dereferenced_value(T *value) {
return *value;
}
template <class Tuple, class Indexes> struct get_dereferenced_tuple_impl;
template <class... Args, size_t... Index>
struct get_dereferenced_tuple_impl<std::tuple<Args...>,
std::integer_sequence<size_t, Index...>> {
decltype(auto) operator()(std::tuple<Args...> const &originalTuple) {
return std::make_tuple(
get_dereferenced_value(std::get<Index>(originalTuple))...);
}
};
template <class Tuple>
decltype(auto) get_dereferenced_tuple(Tuple const &tupleValue) {
return get_dereferenced_tuple_impl<
Tuple,
std::make_integer_sequence<size_t, std::tuple_size<Tuple>::value>>{}(
tupleValue);
}
int main() {
char c = 'i';
std::tuple<char, char *> t{'h', &c};
auto t2 = get_dereferenced_tuple(t);
std::cout << std::get<0>(t2) << std::get<1>(t2) << "\n";
return 0;
}
If you cannot use C++14, then you would have to write more verbose decltype expressions, as well as include an implementation of std::(make_)integer_sequence.
This has a drawback though : copies will be made before copying the bytes. A tuple of references is not a good idea. The most performant version would be a get_bytes able to serialize the entire mixed tuple directly.

how to recursive acquire variadic function parameter with variadic template argument in c++ 11?

I'm working on my own Lua engine with C++ 11, I want to write a function wrapper that register C++ function to Lua environment with variadic parameter. That's simple in C++ 0x, but boring cause I need to write similar codes to support function with 0~N parameters.
function push is used to push T to lua stack, where function upvalue_ get C++ function pointer with lua cclosure, and it assume the funtion is has two parameters T1 and T2, T1 is acquired from lua stack with index 1, and T2 is acquired from lua stack with index 2.
template <typename RVal, typename T1, typename T2>
struct functor<RVal,T1,T2>
{
static int invoke(lua_State *L)
{
push(L,upvalue_<RVal(*)(T1,T2)>(L)(read<T1>(L,1),read<T2>(L,2)));
return 1;
}
};
template<typename T>
T upvalue_(lua_State *L)
{
return user2type<T>::invoke(L, lua_upvalueindex(1));
}
and with C++ 11, I wrote such code snippets:
template< typename RVal, typename ... ARGS>
struct functor
{
static int invoke(lua_State* L)
{
typedef RVal (*FUNC_PTR)(ARGS...);
FUNC_PTR f = upvalue_<FUNC_PTR>(L);
push(L, f(read_stack<ARGS>(L)...));
return 1;
}
};
template<typename T>
T read_stack(lua_State* L)
{
T t = read<T>(L, -1);
lua_pop(L, 1);
return t;
}
the code shown above could work, but the parameter order is reversed because read_stack read parameter from the last index -1 always.
my question is how to read parameter from lua stack from 1 to N(N equals to sizeof...(ARGS) if ARGS not empty) with variadic template argument and pass them to real function pointer f to make real call?
Not specific to Lua, here is a general-purpose C++11 solution to reversing the order of given parameters to a function. In the below code, 'apply' is my example target function (here it just outputs a bit of text based on its variadic parameters). The 'main' functions shows how the helper function 'reverse_and_apply' takes a function (or Functor to be precise) and a set of arguments, and applies the given function to the reversed argument list using some template trickery. Note I apologise for the somewhat anal use of perfect forwarding here, which is technically correct but unfortunately obfuscates the code somewhat. Hopefully you get the main message.
#include <iostream>
template <typename ...Args>
void apply(const char* fmtString, const Args&... args)
{
char output[512];
snprintf(output, 512, fmtString, args...);
std::cout << output << std::endl;
}
template <typename F, typename ...Args>
struct ReverseAndApply;
template <typename F>
struct ReverseAndApply<F>
{
template <typename ... AlreadyReversed>
static void doIt(F func, AlreadyReversed&& ... args)
{
func(args...);
}
};
template <typename F, typename FirstArg, typename ...RestArgs>
struct ReverseAndApply<F, FirstArg, RestArgs...>
{
template <typename ... AlreadyReversed>
static void doIt(F func, FirstArg&& arg, RestArgs&& ... restArgs, AlreadyReversed&& ... revArgs)
{
ReverseAndApply<F, RestArgs...>::doIt(func, std::forward<RestArgs>(restArgs)..., std::forward<FirstArg>(arg), std::forward<AlreadyReversed>(revArgs)...);
}
};
template <typename F, typename... Args>
void reverse_and_apply(F func, Args&&... args)
{
ReverseAndApply<F, Args...>::doIt(func, std::forward<Args>(args)...);
}
int main()
{
reverse_and_apply(apply<double, const char*, int>, 1, (const char*)"abc", 2.0, "%f %s %d");
return 0;
}
Your code in C++11 not even work as the evaluation order of arguments is not defined.
It should be easy by using std::integer_sequence in C++14.
Sample code:
template< typename RVal, typename... ARGS>
struct functor
{
template <std::size_t... Is>
static int invoke_impl(lua_State *L, std::index_sequence<Is...>)
{
typedef RVal (*FUNC_PTR)(ARGS...);
FUNC_PTR f = upvalue_<FUNC_PTR>(L);
push(L, f(read<ARGS>(L, Is)...));
return 1;
}
static int invoke(lua_State* L)
{
return invoke_impl(L, std::index_sequence_for<ARGS...>{});
}
};

Fusion adaped std_tuple views, conversion to another tuple

Boost Fusion has been designed in such a way that most of the transformations are "lazy", in the sense that they all generate "views" but not actual (Fusion) containers (http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/algorithm.html). So for example to actually reverse a vector one needs to use the conversion function as_vector (http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/container/conversion/functions.html).
boost::fusion::vector<int, double, std::string> vec;
auto view_rev = boost::fusion::reverse(vec); // view object
auto vec_rev = boost::fusion::as_vector(view_rev);
Now, I want to do this with adapted std::tuple:
#include<boost/fusion/adapted/std_tuple.hpp>
...
std::tuple<int, double, std::string> tup;
auto view_rev = boost::fusion::reverse(tup);
auto tup_rev = boost::fusion::???(view_rev); // type should be of type std::tuple<std::string, double, int>
How do I convert the resulting view back to a tuple?
I expected this ??? function to be called as_std_tuple (in analogy to boost::fusion::as_vector, but it doesn't exists (yet?).
There a few solutions for reversing tuples, in this case I want just to use what is already in Boost Fusion.
I am not aware of any built-in method to convert a Boost Fusion Sequence into a std::tuple, but using the indices trick it can be implemented rather easily:
template <std::size_t... Is>
struct indices {};
template <std::size_t N, std::size_t... Is>
struct build_indices
: build_indices<N-1, N-1, Is...> {};
template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};
template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
return std::tie(boost::fusion::at_c<Is>(s)...);
}
template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
return as_std_tuple_impl(s, Indices());
}
Here is a full example that reverses an adapted std::tuple using boost::fusion::reverse and converts it back into a std::tuple and prints both tuples:
#include <tuple>
#include <utility>
#include<boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/transformation/reverse.hpp>
#include <boost/fusion/include/reverse.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>
#include <iostream>
template <std::size_t... Is>
struct indices {};
template <std::size_t N, std::size_t... Is>
struct build_indices
: build_indices<N-1, N-1, Is...> {};
template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};
template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
return std::tie(boost::fusion::at_c<Is>(s)...);
}
template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
return as_std_tuple_impl(s, Indices());
}
template<class Tuple, std::size_t N>
struct TuplePrinter
{
static void print(const Tuple& t)
{
TuplePrinter<Tuple, N-1>::print(t);
std::cout << ", " << std::get<N-1>(t);
}
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
static void print(const Tuple& t)
{
std::cout << std::get<0>(t);
}
};
template<class... Args>
void print(const std::tuple<Args...>& t)
{
std::cout << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
std::cout << ")\n";
}
int main()
{
std::tuple<int, double, std::string> tup(1,2.5,"hello");
auto view_rev = boost::fusion::reverse(tup);
auto reversed_tup = as_std_tuple(view_rev);
print(tup);
print(reversed_tup);
return 0;
}
output:
(1, 2.5, hello)
(hello, 2.5, 1)
Live example on ideone

Cannot iterate on a non-copyable container returned by a function

I'm not sure of the title, because I'm not sure the issue comes from the "copyablility" of my container.
I tryied quite everything but I can't get rid of this error.
Here is a simplified version of my code (please do not challenge the class design, I really would like to keep the end-used syntax in the BOOST_FOREACH):
template <typename T>
class MyContainer
{
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
MyContainer(std::vector<T>& vec, boost::mutex& mutex) :
m_vector(vec),
m_lock(mutex)
{
}
iterator begin() { return m_vector.begin(); }
const_iterator begin() const { return m_vector.begin(); }
iterator end() { return m_vector.end(); }
const_iterator end() const { return m_vector.end(); }
private:
std::vector<T>& m_vector;
boost::lock_guard<boost::mutex> m_lock;
};
template <typename T>
struct GetContainer
{
GetContainer(std::vector<T>& vec, boost::mutex& mutex) :
m_vector(vec),
m_mutex(mutex)
{
}
MyContainer<T> Get()
{
return MyContainer<T>(m_vector, m_mutex);
}
std::vector<T>& m_vector;
boost::mutex& m_mutex;
};
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
boost::mutex m;
GetContainer<int> getter(v, m);
BOOST_FOREACH(int i, getter.Get())
{
std::cout << i << std::endl;
}
return 0;
}
The compiler complains about not having a copy constructor for MyContainer::MyContainer(const MyContainer&).
I also have :
error: no matching function for call to ‘MyContainer::MyContainer(boost::foreach_detail_::rvalue_probe >::value_type)’
I follow the extensibility tips:
http://www.boost.org/doc/libs/1_58_0/doc/html/foreach/extensibility.html#foreach.extensibility.making__literal_boost_foreach__literal__work_with_non_copyable_sequence_types
But, making
MyContainer<T> : private boost::noncopyable
doesn't solve the issue.
Nor defining the function
boost_foreach_is_noncopyable
or specializing the template struct
is_noncopyable
for MyContainer (in fact, how would I specialize this template for a template type ?)
Last "tip":
If I remove the mutex and the lock from everywhere (I just pass the vector to GetContainer and to MyContainer), it works.
But it doesn't work if I make
MyContainer<T> : private boost::noncopyable
(I expected it should, so I'm not sure my problem is with BOOST_FOREACH, but maybe because I return a copy of MyContainer with my getter ?)
I thank you if you read me until here, and thanks in advance for help.
Seems to be a limitation of BOOST_FOREACH with move-only types. I didn't find a way around it¹ (except for the - ugly - obvious approach to put the lock_guard in a shared_ptr).
You didn't specify a c++03 requirement, though, so you can make it work without BOOST_FOREACH by replacing lock_guard with unique_lock.
Here's my take on things in c++11 (note how generic it is):
Live On Coliru
#include <boost/thread.hpp>
#include <boost/range.hpp>
namespace detail {
template <typename R, typename M>
struct RangeLock {
RangeLock(R&r, M& m) : _r(r), _l(m) {}
RangeLock(RangeLock&&) = default;
using iterator = typename boost::range_iterator<R>::type;
iterator begin() { using std::begin; return begin(_r); }
iterator end () { using std::end; return end (_r); }
using const_iterator = typename boost::range_iterator<R const>::type;
const_iterator begin() const { using std::begin; return begin(_r); }
const_iterator end () const { using std::end; return end (_r); }
private:
R& _r;
boost::unique_lock<M> _l;
};
}
template <typename R, typename M>
detail::RangeLock<R,M> make_range_lock(R& r, M& mx) { return {r,mx}; }
template <typename R, typename M>
detail::RangeLock<R const,M> make_range_lock(R const& r, M& mx) { return {r,mx}; }
#include <vector>
#include <map>
int main() {
boost::mutex mx;
std::vector<int> const vec { 1, 2 };
std::map<int, std::string> const map { { 1, "one" }, { 2, "two" } };
for(int i : make_range_lock(vec, mx))
std::cout << i << std::endl;
for(auto& p : make_range_lock(map, mx))
std::cout << p.second << std::endl;
for(auto& p : make_range_lock(boost::make_iterator_range(map.equal_range(1)), mx))
std::cout << p.second << std::endl;
}
Prints
1
2
one
two
one
¹ not even using all the approaches from Using BOOST_FOREACH with a constant intrusive list
I post my answer if it can help...
With C++03, I finally provide a copy constructor to be able to use the class with BOOST_FOREACH.
So the issue is moved to another topic: make the class copied in a logic and suitable way.
In my case, I "share the lock and the vector", the user shouldn't use this copy itself if he doesn't want to do bugs, but in BOOST_FOREACH it's okay:
I change the mutex to a recursive_mutex
I change the lock to an unique_lock
and:
MyContainer(const MyContainer& other) :
m_vector(other.vec),
m_lock(*other.m_lock.mutex())
{
}
With C++11
Thanks to Chris Glover on the boost mailling list, a C++11 solution:
You can't do what you are trying to do in C++03. To accomplish it, you
need C++11 move semantics to be able to move the MyContainer out of the Get
function. Even without using BOOST_FOREACH, the following code fails;
GetContainer<int> getter(v, m);
MyContainer<int> c = getter.Get(); // <-- Error.
Here's an example with the necessary changes; I changed the scoped_lock to
a unique_lock and added a move constructor.
template <typename T>
class MyContainer
{
public:
[...]
MyContainer(MyContainer&& other)
: m_vector(other.m_vector)
{
m_lock = std::move(other.m_lock);
other.m_vector = nullptr;
}

Resources