Function template parameter - c++

I ran into the following code that defines a function template in a class:
#include <cstdint>
class foo {
public:
enum class magic_type : std::uint32_t {
START = 0,
BLUE = 0xFF000001,
RED,
};
struct header_t {
uint32_t version;
magic_type magic;
};
template <typename T>
static bool is_of_type(header_t *h)
{
return (h->magic == T::magic_type);
}
foo(uint32_t ver, foo::magic_type mag)
{
header.version = ver;
header.magic = mag;
}
header_t header;
};
I am finding the implementation of 'is_of_type` confusing. The code as is compiles, so syntactically must be correct. However, this method is not invoked from any other part of the program, so I am not sure what the intent of the function is (lack of documentation). I figured there could be two interpretation of the function:
Return true/false based on the magic type of an object and the specific enum type passed as the function template parameter.
E.g. An invocation of the method would be:
foo bar(1.2, foo::magic_type::BLUE);
bool temp = bar.is_of_type<foo::magic_type::BLUE>(&(bar.header));
However, in the above case, I am not really passing a type (as in an int, or char, etc). Right? The code does not compile.
Return true/false if the magic type is a valid enum.
In this case, I am assuming the function does not need to be templated, and could be re-written as:
static bool is_of_type(header_t *h)
{
return (h->magic == foo::magic_type);
}
E.g. of an invocation:
foo bar(1.2, foo::magic_type::BLUE);
bool temp = bar.is_of_type(&(bar.header));
Again, getting compile error. I tried using "typename", but my attempts were futile.
Can someone please help me with proper implementation of is_of_type for the above two cases and an invocation example.

The invocation would be with an explicitly specified type, which has a nested static member called magic_type.
For instance, it could be called as follows:
struct test {
static foo::magic_type const magic_type;
};
foo::magic_type const test::magic_type = 42;
foo bar{1, foo::magic_type::BLUE};
bar.is_of_type<test>(bar.header);
The fact that magic_type is used twice, once for an enum class and once for a static variable, is very confusing though.

Related

How to use Objective-C sources' ExplicitInit class?

In the Objc source code, I found the following code. What is the meaning of this code and how to understand it?
objc/Project Headers/DenseMapExtras.h line:38
template <typename Type>
class ExplicitInit {
alignas(Type) uint8_t _storage[sizeof(Type)];
public:
template <typename... Ts>
void init(Ts &&... Args) {
new (_storage) Type(std::forward<Ts>(Args)...);
}
Type &get() {
return *reinterpret_cast<Type *>(_storage);
}
};
Below is my test code:
class MyC{
public:
long l1;
long l2;
MyC(long _l1, long _l2){
l1 = _l1;
l2 = _l2;
}
};
int main(){
MyExplicitInit<MyC> e1 {};
e1.init();
return 0;
}
The compiler prompts the following error:
In the Objc source code, I found the following code. What is the
meaning of this code and how to understand it?
To me it looks like a kind-of-factory which can be used as an alternative to the Construct On First Use Idiom. An instantiated class here represents a storage for an instance you can initialise and request when needed. As far as I understand it's not supposed to be used for local variables (it doesn't make much sense, despite being technically possible) and this is also suggested by the comments of code section with the said class template:
// We cannot use a C++ static initializer to initialize certain globals because
// libc calls us before our C++ initializers run. We also don't want a global
// pointer to some globals because of the extra indirection.
//
// ExplicitInit / LazyInit wrap doing it the hard way
For the error you are experiencing:
No matching operator new function for non-allocating placement new expression;
include <new>
Assuming that you just added that piece of code somewhere in your own sources, the problem here is that you didn't include the <new> header. As simple as that - the error just says that you need to add #include <new> since so-called placement new is not part of the "default" C++, it's an overloaded operator declared in this header.
Second, your init function expects arguments that matches one of the existing (non-aggregate) constructors of the given class, so you are expected to pass arguments which are either match the constructor parameters or can be implicitly converted to them: e1.init(1l, 2l)
A complete example looks something like this:
#include <_types/_uint8_t.h>
#include <new>
namespace objc {
template <typename Type>
class ExplicitInit {
alignas(Type) uint8_t _storage[sizeof(Type)];
public:
template <typename... Ts>
void init(Ts &&... Args) {
new (_storage) Type(std::forward<Ts>(Args)...);
}
Type &get() {
return *reinterpret_cast<Type *>(_storage);
}
};
};
struct sample_struct {
long l1, l2;
sample_struct(long _l1, long _l2): l1{_l1}, l2{_l2} {}
};
sample_struct& getInstance(bool should_init = false) {
static objc::ExplicitInit<sample_struct> factory;
if (should_init) {
factory.init(1l, 2l);
}
return factory.get();
}

Check for symbol is a [pointer to] member function/field in D

In C++ we can easily detect that given type is a pointer to member function/field:
template< class T >
struct is_member_pointer : std::false_type {};
template< class T, class U >
struct is_member_pointer<T U::*> : std::true_type {};
There are no such syntax in D (I mean T U::*). Moreover, free functions and methods have the same type:
void func();
struct S
{
int x;
void func() {}
}
static assert(is(typeof(func) == typeof(S.func)));
So, my question is: can we write in D a template which is analogous to C++-version?
template is_member_of(alias M)
{
alias T = /**/;
}
static assert(is(is_member_of!(S.func) == S));
static assert(is(is_member_of!func == void));
static assert(is(is_member_of!(S.x) == S));
Try taking the address of the function via the init object instead:
static assert(is(typeof(&func) == typeof(&S.init.func)));
Will give:
ooo.d(9): Error: static assert: is(void function() == void delegate()) is false
The member function (unless it is static, but then it isn't really a member function) will be typed delegate because it requires a this object, whereas the other one will be typed function.
That will work for the function, and you can do something similar with the variable (tip: static assert: is(typeof(& x)) is false, but static assert(is(typeof(&S.init.x)); passes - note the .init) if you are curious about if it is an actual member, with a runtime this requirement (that is, not static).
I'll leave turning this information into a template check as an exercise to the reader (tip though: is(typeof(something) == delegate) is a thing in the language...)
But, if you want to just know if there's a parent type on the symbol, there's a different way: just ask the compiler if there's a parent! OK, I confess the code is slightly longer to get the void response your static asserts were looking for, but not much:
// identity template to hack around parser limitations
// this is common when using the __traits stuff, alas.
alias I(alias T) = T;
template is_member_of(alias M) {
// if it has a parent, return it, otherwise, return void
static if(is(I!(__traits(parent, M))))
alias is_member_of = I!(__traits(parent, M));
else
alias is_member_of = void;
}
You might furthermore check if the parent is certain things like struct or class, but really, if it exists at all it is probably what you're looking for.

How can I bundle additional information to an enum?

Let's say I have an enumeration of statuses for a game I'm working on. At first, I have something like this:
enum class Status {
OK, HURT, DYING, DEAD
};
That's all fine and dandy, but now I want to print the name of the status. Naturally, if this was a normal class, I would call getName() on an instance of Status. However, no such option exists for an enumeration.
A way to solve this problem is to have something like this:
const char * getName(Status status) {
switch(status) {
case Status::OK:
return "OK";
break;
/*and so on */
}
However, this is clearly not very extensible. It becomes a problem when you have a lot of enums with lots of data tied to them. You also don't really tie related data together in a very meaningful way. With uniform call syntax, you could get something close, like this:
Status::OK.getName();
But that's not standard yet.
Another way to solve this problem is through static const members inside a class, like so:
class Status {
std::string name;
Status(std::string name):name(std::move(name)) {}
public:
const std::string & getName() const { return name; }
static const Status OK, HURT, DYING, DEAD;
};
//in some .cpp
const Status Status::OK("OK"), Status::HURT("Hurt"), Status::DYING("Dying"), Status::DEAD("Dead");
That's all well and good, and it works out fine, for a while. But now, I want to write some code to deal with each Status, so instinctively I prefer a switch over an if-else chain.
I write this:
Status status = getStatus();
switch(status) {
case Status::OK:
//do something
default:
//do something else
}
Of course, this doesn't work. I need a converting operator! So I add that
operator int() { return /*some sort of unique value*/; }
And... still nothing. The reasoning is that the operator must be a constexpr. Which is obvious, knowing the detail of switch, but it doesn't really help. So the next logical step is to have the static consts become static constexprs.
class Status {
const char * name; //we are in constexpr land now
constexpr Status(const char * name):name(name) {}
public:
constexpr const char * getName() const { return name; }
constexpr operator int() const { return /*some sort of unique value*/; }
static constexpr Status OK = Status("OK"),
HURT = Status("Hurt"),
DYING = Status("Dying"),
DEAD = Status("Dead");
};
//in some .cpp
constexpr Status Status::OK, Status::HURT, Status::DYING, Status::DEAD;
The reason for having to put the statics is because constexpr have to be initialized on the spot. This would work fine, and honestly it covers all my needs. The only problem is that it doesn't compile. It makes sense: how can a class whose definition is not done yet be initialized? This is not a problem with the consts, because they are delayed in their instantiation.
So now, the only reasonable way to do something like that is through a another class, so that the size of Status is known when we create the constexprs.
class Status {
const char * name;
constexpr Status(const char * name):name(name) {}
public:
constexpr const char * getName() const { return name; }
constexpr operator int() const { return /*some sort of unique value*/; }
struct constants;
};
struct Status::constants {
static constexpr Status OK = Status("OK"),
HURT = Status("Hurt"),
DYING = Status("Dying"),
DEAD = Status("Dead");
};
//in some .cpp
constexpr Status Status::constants::OK, Status::constants::HURT, Status::constants::DYING, Status::constants::DEAD;
It's a distance away from the natural syntax of Status::NAME, instead having to say something like Status::constants::NAME. Another concern is the operator int(). There is no way (that I know of) to make this be populated in a way such as an enum would be. In a static const implementation, the obvious choice is to have a private static int, increment it in the ctor, and store it, using that as the return value of the conversion operator. However, this is no longer an option in the constexpr version. Maybe there's some sort of template magic to do it, and if so I'd love to see it. So my question is, are there any improvements to be done using modern C++ to the way we bundle information to an enum?
Based on Columbo's answer here: Is a class definition complete when it is passed to a base class?, it is possible to achieve expanded enums.
template<class T>
class Constants {
public:
static const T OK, HURT, DYING, DEAD;
};
template <typename T>
constexpr T Constants<T>::OK = T("OK");
template <typename T>
constexpr T Constants<T>::HURT = T("Hurt");
template <typename T>
constexpr T Constants<T>::DYING = T("Dying");
template <typename T>
constexpr T Constants<T>::DEAD = T("Dead");
class Status : public Constants<Status> {
friend class Constants<Status>;
const char * name;
constexpr Status(const char * name):name(name) {}
public:
constexpr const char * getName() const { return name; }
constexpr operator int() const { return /*some sort of unique value*/; }
};
While there are still some issues with this implementation, such as a lack of returning a unique value (probably have to just make the ctor take one and do it manually), it looks pretty good. Note however this won't compile on MSVC (due to lack of good constexpr support) or Clang (due to bug 24541). But hey, it's the best we've got so far.

variadic templates: invalid use of void expression

I'm trying to create a generic collection for events so that it'll be reusable for different kind of event-sets. While playing around with variadic templates, I came across THIS answer, which helped me for my example here:
#include <boost/test/unit_test.hpp>
#include <string>
#include <unordered_map>
namespace
{
struct Event3 {
static const int event_type = 3;
int a;
};
struct Event5 {
static const int event_type = 5;
double d;
};
struct Event7 {
static const int event_type = 7;
std::string s;
};
template <class ...K>
void gun(K...) {}
template <class... Ts>
class EventCollection
{
template <typename T>
void update_map(std::unordered_map<int, size_t> & map, const T &)
{
BOOST_CHECK(map.find(T::event_type) == map.end());
map[T::event_type] = sizeof(T);
}
public:
std::unordered_map<int, size_t> curr_map;
EventCollection(Ts... ts)
{
gun(update_map(curr_map, ts)...); // will expand for each input type
}
};
} // namespace
BOOST_AUTO_TEST_CASE( test_01 )
{
Event3 x{13};
Event5 y{17.0};
Event7 z{"23"};
EventCollection<Event3, Event5, Event7> hoshi(x, y, z);
BOOST_CHECK_EQUAL(hoshi.curr_map.size(), 3);
}
However, the line
gun(update_map(curr_map, ts)...); // will expand for each input type
gives me an 'error: invalid use of void expression'.
Can anybody tell me, how to solve this?
The problem is that your update_map returns void. Hence you cannot write this:
gun(update_map(curr_map, ts)...);
because the return values of update_map is supposed to be passed to gun as arguments.
The fix is to pass something to gun as argument, so you can do this:
gun( (update_map(curr_map, ts),0)...);
Now the expresssion (update_map(curr_map, ts),0) turns out to be 0 which is passed as argument to gun. That should work. You can think of this as:
T argmument = (update_map(curr_map, ts),0); //argument is 0, and T is int
--
Also, as the other answer pointed out that the order of evaluation of arguments to gun() are unspecified (means the order in which the function update_map is called, is unspecified) which may lead to undesired result. The other solution has given a solution to this problem. Here is another one (which is a bit tricky and easy!):
//ensure that the size of the below array is at least one.
int do_in_order[] = {0, (update_map(curr_map, ts),0)...};
Because the order of initialization of array elements are well-defined (from left-to-right), now all the calls to update_map happens in well-defined order.
update_map is a function that returns void.
That line consists of calling update_map, and then passing the return value to gun.
You cannot pass a void return value to another function.
Hence "invalid use of void expression".
There are many ways to fix this, including having update_map return struct empty {};
Note that your code results in the calls of update_map happening in an unspecified order. This can easily lead to unexpected behavior.
Might I suggest:
void do_in_order();
template<typename F0, typename... Functors>
void do_in_order( F0&& f0, Functors&& funcs... ) {
f0();
do_in_order( std::forward<Functors>(funcs)... );
}
then replace the call to gun with:
do_in_order([&]{update_map(curr_map, ts);}...); // will expand for each input type
which packages up the things to do into lambdas, which are then called in order that they are passed.
Now, this also does away with the need for an update_map function entirely:
do_in_order([&]{
BOOST_CHECK(curr_map.find(ts::event_type) == curr_map.end());
map[ts::event_type] = sizeof(ts);
}...);
which is awesome.

How is LLVM isa<> implemented?

From http://llvm.org/docs/CodingStandards.html#ci_rtti_exceptions
LLVM does make extensive use of a
hand-rolled form of RTTI that use
templates like isa<>, cast<>, and
dyn_cast<>. This form of RTTI is
opt-in and can be added to any class.
It is also substantially more
efficient than dynamic_cast<>.
How is isa and the others implemented?
First of all, the LLVM system is extremely specific and not at all a drop-in replacement for the RTTI system.
Premises
For most classes, it is unnecessary to generate RTTI information
When it is required, the information only makes sense within a given hierarchy
We preclude multi-inheritance from this system
Identifying an object class
Take a simple hierarchy, for example:
struct Base {}; /* abstract */
struct DerivedLeft: Base {}; /* abstract */
struct DerivedRight:Base {};
struct MostDerivedL1: DerivedLeft {};
struct MostDerivedL2: DerivedLeft {};
struct MostDerivedR: DerivedRight {};
We will create an enum specific to this hierarchy, with an enum member for each of the hierarchy member that can be instantiated (the others would be useless).
enum BaseId {
DerivedRightId,
MostDerivedL1Id,
MostDerivedL2Id,
MostDerivedRId
};
Then, the Base class will be augmented with a method that will return this enum.
struct Base {
static inline bool classof(Base const*) { return true; }
Base(BaseId id): Id(id) {}
BaseId getValueID() const { return Id; }
BaseId Id;
};
And each concrete class is augmented too, in this manner:
struct DerivedRight: Base {
static inline bool classof(DerivedRight const*) { return true; }
static inline bool classof(Base const* B) {
switch(B->getValueID()) {
case DerivedRightId: case MostDerivedRId: return true;
default: return false;
}
}
DerivedRight(BaseId id = DerivedRightId): Base(id) {}
};
Now, it is possible, simply, to query the exact type, for casting.
Hiding implementation details
Having the users murking with getValueID would be troublesome though, so in LLVM this is hidden with the use of classof methods.
A given class should implement two classof methods: one for its deepest base (with a test of the suitable values of BaseId) and one for itself (pure optimization). For example:
struct MostDerivedL1: DerivedLeft {
static inline bool classof(MostDerivedL1 const*) { return true; }
static inline bool classof(Base const* B) {
return B->getValueID() == MostDerivedL1Id;
}
MostDerivedL1(): DerivedLeft(MostDerivedL1Id) {}
};
This way, we can check whether a cast is possible or not through the templates:
template <typename To, typename From>
bool isa(From const& f) {
return To::classof(&f);
}
Imagine for a moment that To is MostDerivedL1:
if From is MostDerivedL1, then we invoke the first overload of classof, and it works
if From is anything other, then we invoke the second overload of classof, and the check uses the enum to determine if the concrete type match.
Hope it's clearer.
Just adding stuff to osgx's answer: basically each class should implement classof() method which does all the necessary stuff. For example, the Value's classof() routine looks like this:
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *) {
return true; // Values are always values.
}
To check whether we have a class of the appropriate type, each class has it's unique ValueID. You can check the full list of ValueID's inside the include/llvm/Value.h file. This ValueID is used as follows (excerpt from Function.h):
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Function *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal;
}
So, in short: every class should implement classof() method which performs the necessary decision. The implementation in question consists of the set of unique ValueIDs. Thus in order to implement classof() one should just compare the ValueID of the argument with own ValueID.
If I remember correctly, the first implementation of isa<> and friends were adopted from boost ~10 years ago. Right now the implementations diverge significantly :)
I should mention that http://llvm.org/docs/ProgrammersManual.html#isa - this document have some additional description.
The source code of isa, cast and dyn_cast is located in single file, and commented a lot.
http://llvm.org/doxygen/Casting_8h_source.html
00047 // isa<X> - Return true if the parameter to the template is an instance of the
00048 // template type argument. Used like this:
00049 //
00050 // if (isa<Type*>(myVal)) { ... }
00051 //
00052 template <typename To, typename From>
00053 struct isa_impl {
00054 static inline bool doit(const From &Val) {
00055 return To::classof(&Val);
00056 }
00057 };
00193 // cast<X> - Return the argument parameter cast to the specified type. This
00194 // casting operator asserts that the type is correct, so it does not return null
00195 // on failure. It does not allow a null argument (use cast_or_null for that).
00196 // It is typically used like this:
00197 //
00198 // cast<Instruction>(myVal)->getParent()
00199 //
00200 template <class X, class Y>
00201 inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
00202 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
00203 return cast_convert_val<X, Y,
00204 typename simplify_type<Y>::SimpleType>::doit(Val);
00205 }
00218 // dyn_cast<X> - Return the argument parameter cast to the specified type. This
00219 // casting operator returns null if the argument is of the wrong type, so it can
00220 // be used to test for a type as well as cast if successful. This should be
00221 // used in the context of an if statement like this:
00222 //
00223 // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
00224 //
00225
00226 template <class X, class Y>
00227 inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
00228 return isa<X>(Val) ? cast<X, Y>(Val) : 0;
00229 }