OpenMP threadprivate variable template - openmp

I want a variable template to be threadprivate as well. Could this be done ? Something like the following:
template<typename T>
struct Tpl { };
template<typename X>
extern Tpl<X> var;
#pragma omp threadprivate(var) // <<< No compiler supports this.
template<typename X>
Tpl<X> var;

Related

How can I use Boost.Hana to determine whether a functor has a call operator that can be invoked with a particular template argument?

In my application, I want to determine at compile time whether an arbitrary functor type Func has a nullary call operator that can be invoked with a given explicit template argument T. Based on a previous SO answer that I found, I came up with the following:
#include <boost/hana.hpp>
#include <iostream>
#include <type_traits>
namespace hana = boost::hana;
namespace detail
{
template <typename T>
auto can_call = hana::is_valid([](auto &&f) ->
decltype(f.template operator()<T>()) { });
}
template <typename Func, typename T>
constexpr auto can_call() ->
decltype(detail::can_call<typename std::remove_reference<T>::type>(
std::declval<Func>())) { return {}; }
struct foo
{
template <typename T, typename =
std::enable_if_t<!std::is_same<T, char>::value>>
void operator()() const { }
};
int main()
{
std::cout << "char: " << can_call<foo, char>() << std::endl;
std::cout << "int: " << can_call<foo, int>() << std::endl;
}
I would expect this example to print out:
char: 0
int: 1
Since the char template argument type is explicitly enable_if-ed out in foo. I've tried the following compilers:
Apple clang v8.0.0: The example compiles and runs as expected.
mainline clang v3.9.1+ (via Wandbox): The example compiles and runs as expected.
mainline clang v3.6.0 - v3.8.1 (via Wandbox): The compiler dies with an internal error.
g++ 7.0 trunk, 20170410 (via Wandbox): The compilation fails with the following errors:
dd.cc: In instantiation of ‘auto detail::can_call<char>’:
dd.cc:15:14: required by substitution of ‘template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call() [with Func = foo; T = char]’
dd.cc:25:50: required from here
dd.cc:10:10: error: ‘auto detail::can_call<char>’ has incomplete type
auto can_call = hana::is_valid([](auto &&f) -> decltype(f.template operator()<T>()) { });
^~~~~~~~
dd.cc: In function ‘int main()’:
dd.cc:25:50: error: no matching function for call to ‘can_call<foo, char>()’
std::cout << "char: " << can_call<foo, char>() << std::endl;
^
dd.cc:14:16: note: candidate: template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call()
constexpr auto can_call() ->
^~~~~~~~
dd.cc:14:16: note: substitution of deduced template arguments resulted in errors seen above
dd.cc: In instantiation of ‘auto detail::can_call<int>’:
dd.cc:15:14: required by substitution of ‘template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call() [with Func = foo; T = int]’
dd.cc:26:48: required from here
dd.cc:10:10: error: ‘auto detail::can_call<int>’ has incomplete type
auto can_call = hana::is_valid([](auto &&f) -> decltype(f.template operator()<T>()) { });
^~~~~~~~
dd.cc:26:48: error: no matching function for call to ‘can_call<foo, int>()’
std::cout << "int: " << can_call<foo, int>() << std::endl;
^
dd.cc:14:16: note: candidate: template<class Func, class T> constexpr decltype (can_call<typename std::remove_reference<_To>::type>(declval<Func>())) can_call()
constexpr auto can_call() ->
^~~~~~~~
dd.cc:14:16: note: substitution of deduced template arguments resulted in errors seen above
It seems to not like my use of hana::is_valid() to determine whether the specified operator exists. However, I think the way I'm using it is consistent with its intended use.
Is this a bug in gcc, a more lenient implementation in contemporary clang versions, or did I implement this type of check incorrectly? It seems like this is definitely within Hana's wheelhouse; I'm just trying to wrap my head around its new model of constexpr metaprogramming.
Here is a workaround that uses a struct "functor" instead of a lambda and an extra layer of indirection for the type of the is_valid instance to appease gcc.
namespace detail
{
template <typename T>
struct check_can_call {
template <typename F>
constexpr auto operator()(F&& f) ->
decltype(f.template operator()<T>()) { }
};
template <typename T>
using is_call_valid = decltype(hana::is_valid(check_can_call<T>{}));
template <typename T>
constexpr is_call_valid<T> can_call{};
}

g++ fails to look up static functions in a template class, is it a bug or standard defined?

When I try some C++11 code like following, it passed in all clang++ available to me that support C++11, but it failed to compile in g++-4.8, g++-4.9 and g++-5.0.
#include <type_traits>
#include <vector>
template <class C, class First, class Last>
struct HasInsertEnd {
template <class U>
static std::false_type Check(...);
template <class U>
static auto Check(U val)
-> decltype(val.insert(val.end(), std::declval<First>(),
std::declval<Last>()),
std::true_type{});
template <class U>
using Deduce = decltype(Check<U>(std::declval<U>()));
using type = typename Deduce<C>::type;
static constexpr bool value = type::value;
};
int main(int argc, char* argv[]) {
static_assert(!HasInsertEnd<int, int, int>::value, "...");
static_assert(HasInsertEnd<std::vector<int>, const int*, const int*>::value,
"...");
return 0;
}
g++ will report errors like:
‘Check’ was not declared in this scope
If I change the calling of Check in the Deduce to HasInsertEnd::Check, both g++ and clang++ will be happy.
I know little about dependent name lookup. The problem is, which behavior is standard?
This is a bug in GCC, and can be shown to be a bug in GCC even without deferring to the standard.
template <typename T>
struct f { typedef int type; };
template <typename T>
struct S {
template <typename U>
static f<U> f();
template <class U>
using u = typename decltype(f<U>())::type;
using t = u<T>;
};
S<int>::t main() { }
This is rejected the same way in GCC 4.7.4 and GCC 5, with "error: ‘f’ was not declared in this scope". That's just nonsense. Even if the static member function should somehow not be visible, there is still a global type by the same name that would be found instead. It gets even better, though: with that global type, you get:
test.cc: In substitution of ‘template<class T> template<class U> using u = typename decltype (f<U>())::type [with U = T; T = T]’:
test.cc:12:20: required from here
test.cc:10:36: error: ‘f’ was not declared in this scope
using u = typename decltype(f<U>())::type;
^
test.cc:10:36: note: suggested alternative:
test.cc:2:12: note: ‘f’
struct f { typedef int type; };
^
test.cc:15:13: error: ‘t’ in ‘struct S<int>’ does not name a type
S<int>::t main() { }
^
That's right, it's suggesting that f can be corrected by spelling it f.
I don't see any problem with your code, and if it isn't a known bug, I encourage you to report it. and it's been reported as a bug before.
Oddly, as noted in the comments, GCC 4.8.4 and GCC 4.9.2 do find a global f. However, if the global f is a type, then they still reject the program, with "error: missing template arguments" even though the template argument is provided, so it's still clearly a bug in GCC.

Creating a new tuple class by popping the last type

I tried the following code but it gives:
main.cpp:29:22: error: aggregate 'pop<std::tuple<int, char, float> > p' has incomplete type and cannot be defined
What am I missing?
template <typename T>
struct pop;
template <typename E, typename... Ts>
struct pop<tuple<Ts..., E>> {
using result = tuple<Ts...>;
};
tuple<int, char, float> t;
typename pop<decltype(t)>::result p;
If Ts... must be at the end in a type list, why does it work in this example from http://en.cppreference.com/w/cpp/language/parameter_pack:
template<class A, class B, class...C> void func(A arg1, B arg2, C...arg3)
{
container<A,B,C...> t1; // expands to container<A,B,E1,E2,E3>
container<C...,A,B> t2; // expands to container<E1,E2,E3,A,B>
container<A,C...,B> t3; // expands to container<A,E1,E2,E3,B>
}
tuple<Ts..., E> is a non-deduced context. [temp.deduct.type]/9:
If P has a form that contains <T> or <i>, then each argument Pi of the respective template argument list P is compared with the corresponding argument Ai of the corresponding template argument list of A. If the template argument list of P contains a pack expansion that is not the last template argument, the entire template argument list is a non-deduced context.
That means that your partial specialization is never matched.
With C++14, one could use
template <class T, class=std::make_index_sequence<std::tuple_size<T>::value-1>>
struct pop;
template <typename Tuple, std::size_t... indices>
struct pop<Tuple, std::index_sequence<indices...>>
{
using type = std::tuple<std::tuple_element_t<indices, Tuple>...>;
};
template <typename T>
using pop_t = typename pop<T>::type;
Such that
using t = std::tuple<int, char, float>;
static_assert( std::is_same<pop_t<t>, std::tuple<int, char>>{}, "" );
Compiles.
Demo.
Ts... must be the last element of a type list if you want it to be deduced. tuple<Ts...,E> will not deduce Ts... to be all but the last, but rather never match anything.
Getting rid of the last argument is a bit tricker. live example:
#include <iostream>
#include <tuple>
#include <iostream>
namespace details {
template<class Lhs, class Rhs>
struct pop_helper;
template<template<class...>class Tup, class L0, class...Lhs, class...Rhs>
struct pop_helper<Tup<L0,Lhs...>, Tup<Rhs...>>:
pop_helper<Tup<Lhs...>, Tup<Rhs...,L0>>
{};
template<template<class...>class Tup, class L0, class...Rhs>
struct pop_helper<Tup<L0>, Tup<Rhs...>> {
using type=Tup<Rhs...>;
};
}
template <typename T>
struct pop;
template<template<class...>class Tup, class...Ts>
struct pop<Tup<Ts...>>:
details::pop_helper<Tup<Ts...>,Tup<>>
{};
template<typename T>
using pop_t=typename pop<T>::type;
std::tuple<int, char, float> t;
typedef pop_t<decltype(t)> p;
int main() {
p x = std::make_tuple( 7, 'x' );
std::cout << std::get<0>(x) << std::get<1>(x) << std::tuple_size<p>{} << "\n";
}
pop_helper moves the types over one at a time to the right hand side, until there is only one type left on the left hand side. Then it returns the right hand side type.
pop just passes the tuples over.
I used template<class...>class Tup instead of std::tuple, because why not support almost every template instead of just std::tuple?
pop_t gets rid of the annoying typename spam at point of use.
I use the inhertance-as-type-map-forwarding pattern, which saves on typing. With a type-map, the structure:
template<class X>
struct bob: foo<X> {};
can be read as bob<X> is foo<X>. The alternative is the more verbose
template<class X>
struct bob {
using type = typename foo<X>::type;
};
expanding variardic type lists is different than matching them. When it was designed, matching was kept simple in order to make compiler vendors be able to implement the feature. There may even be thorny issues beyond "it is tricky" down that path.
Another C++11 way to skin this cat:
#include <tuple>
template<class Tuple>
struct pop;
template<>
struct pop<std::tuple<>>
{
using type = std::tuple<>;
};
template<typename T1>
struct pop<std::tuple<T1>>
{
using type = std::tuple<>;
};
template<typename First, typename... Rest>
struct pop<std::tuple<First,Rest...>>
{
using type =
decltype(std::tuple_cat(
std::declval<std::tuple<First>>(),
std::declval<typename pop<std::tuple<Rest...>>::type>()));
};
// Test...
static_assert(std::is_same<pop<std::tuple<>>::type,std::tuple<>>::value,"");
static_assert(std::is_same<pop<std::tuple<int>>::type,std::tuple<>>::value,"");
static_assert(
std::is_same<pop<std::tuple<int,char>>::type,std::tuple<int>>::value,"");
static_assert(
std::is_same<pop<std::tuple<int,char,float>>::type,
std::tuple<int,char>>::value,"");
static_assert(
std::is_same<pop<std::tuple<int,char,float,double>>::type,
std::tuple<int,char,float>>::value,"");
This is the solution I had come up with:
template <typename T>
struct pop;
template <typename E, typename... Ts>
struct pop<std::tuple<E, Ts...>> {
using type = decltype(tuple_cat(
declval<tuple<E>>(),
declval<typename pop<tuple<Ts...>>::type>()
));
};
template <typename E>
struct pop<std::tuple<E>> {
using type = std::tuple<>;
};

Second scope after struct definition

I looked a bit into Eric Nieblers range library https://github.com/ericniebler/range-v3/ and there (/include/range/v3/utility/concepts.hpp, line 36) I found code of the form
constexpr struct valid_expr_t
{
template<typename ...T>
true_ operator()(T &&...) const;
} valid_expr {};
I am confused to the second scope/braces after valid_expr. What is the meaning of the whole construct. Is this even a struct definition? The syntax seems not allowed in C++98. What can go into these second pair of braces?
It's the C++11 uniform initialization syntax, and it simply initializes the valid_expr object.
It's like doing
struct valid_expr_t
{
template<typename ...T>
true_ operator()(T &&...) const;
};
constexpr valid_expr_t valid_expr {};

Can we use parameter packs as std::vector initializers?

I'm experimenting with C++11 (I've used old C++ so far) and I wrote the following code:
#include <iostream>
#include <vector>
#include <type_traits>
using namespace std;
constexpr bool all_true(){
return true;
}
template <typename Head, typename... Tail>
constexpr bool all_true(Head head, Tail... tail){
static_assert( is_convertible<bool, Head>::value, "all_true arguments must be convertible to bool!");
return static_cast<bool>(head) && all_true(tail...);
}
template<typename T, typename... Args>
void print_as(Args... args){
static_assert( all_true(is_convertible<T,Args>::value...), "all arguments must be convertible to the specified type!");
vector<T> v {static_cast<T>(args)...};
for(T i : v) cout << i << endl;
}
int main(){
print_as<bool>(1, 2, 0, 4.1);
}
The code compiles and runs as expected (I used gcc 4.6). I would like to aks the following questions:
I initialized a std::vector with an expanded parameter pack ( vector v {static_cast(args)...}; ). Is this correct C++11? I haven't found this feature explained anywhere.
I don't like too much the declaration of all_true because I know the type but I use templates. Is it possible to use something similar to the following?
constexpr bool all_true(bool head, bool... tail){...} // This code doesn't compile
Thanks!
Yes, it is possible to use pack expansions inside initialiser lists. C++11 [temp.variadic]§4 allows this:
... Pack expansions can occur in the following contexts:
...
In an initializer-list (8.5); the pattern is an initializer-clause.
No, there's no way to make a non-template typesafe variadic function. What you have is OK. There was a question about this recently.

Resources