c++ create dynamic type - c++

I have the following situation: Depending on some parameter that my function takes it have to create different types:
I want to do something like this:
if(variant==1){
#define my_type int;
}
else{
#define my_type double;
}
cout<<sizeof(my_type);
and then use my_type in my further code.
So, that in case of variant=1 sizeof(my_type) gives 4 and for variant=2 it gives 8.
How can this be done? Either in this manner or another.
Thanks.

I agree with #Magnus Hoff in that what you asked cannot be done. But there are two approximations.
Option 1: make variant a macro.
#ifdef variant
# define my_type int
#else
# define my_type double
#endif
Option 2: use template function.
Instead of
void func(int variant) {
if (variant==1)
#define my_type int
else
#define my_type double
my_type ...
}
do this:
template<typename my_type> void func() {
my_type ...
}

Replace this:
if(variant==1){
#define my_type int;
}
else{
#define my_type double;
}
cout<<sizeof(my_type);
… with this:
template< class Type >
void foo()
{
// ...
cout<<sizeof(Type);
}
// ...
if( variant==1 )
{
foo<int>();
}
else
{
foo<double>();
}
Note that a runtime value can't affect compile time decisions. Without a time travel device.

Related

Preprocessor: concat previous line number in the name of a structure

I know how to declare a struct where the name contains the current line number. The following code works as expected.
#define CREATE_NAME_CONCAT_(X, Y) X ## Y
#define CREATE_NAME_CONCAT(X, Y) CREATE_NAME_CONCAT_(X, Y)
#define CREATE_FOO_NAME CREATE_NAME_CONCAT(Foo_, __LINE__)
struct CREATE_FOO_NAME { int x; };
typedef Foo_4 Foo;
int main()
{
Foo foo;
foo.x = 42;
return 0;
}
How can I write the typedef line using the previous line number ? The following code doesn't work:
#define CREATE_NAME_CONCAT_(X, Y) X ## Y
#define CREATE_NAME_CONCAT(X, Y) CREATE_NAME_CONCAT_(X, Y)
#define CREATE_FOO_NAME CREATE_NAME_CONCAT(Foo_, __LINE__)
struct CREATE_FOO_NAME { int x; };
typedef CREATE_NAME_CONCAT(Foo_, __LINE__-1) Foo;
int main()
{
Foo foo;
foo.x = 42;
return 0;
}
Note 1: yes I have a good reason to do that
Note 2: I don't use C++11 or more recent
Note 3: I don't want to debate notes 1 & 2
The preprocessor is pretty limited, the best solution is to not use it at all. You can accomplish something similar with templates:
template <int>
struct FooT;
template <>
struct FooT<__LINE__> { int x; };
typedef FooT<__LINE__-1> Foo;
int main()
{
Foo foo;
foo.x = 42;
return 0;
}
I don't know if this meets your requirements as they seem to be secret.

How to initialize lookup-table static std::array, a private member of a class, defined with constexpr length based on bit length of int

Trying to create a class which acts as a tool to amplify/attenuate some value based on lookup tables.
Foo.h
#ifndef FOO_H
#define FOO_H
#include <array>
#include <limits>
class Foo
{
public:
Foo();
~Foo();
static double applySomeFoo(double f, unsigned int amplify_by);
private:
static constexpr int m_BITS_IN_INT {std::numeric_limits<int>.digits};
static std:array<double, m_BITS_IN_INT> m_fooFactors /***?** Don't know what to put here! */;
// **?** Tried {{}}, {} and nothing and {{...}} and {...} and {{{}}} then scratched head...
};
#endif
Foo.cpp
#include <assert>
#include "Foo.h"
double Foo::applySomeFoo(double f, unsigned int amplify_by)
{
assert(amplify_by < Foo::m_BITS_IN_INT);
return (f * Foo::m_fooFactors.at(amplify_by));
}
// FOO
Foo::Foo() : /**?** Don't know what to put here! */
{
// ctor
// Populate the lookup table
int i {0};
for(auto &x : Foo::m_fooFactors)
{
x = static_cast<double>(2 ^ i++);
}
}
Foo::~Foo()
{
// dtor
}
I'm new to C++.
It fails to compile and I don't really understand how to instantiate so I can then populate the static array with values since it has a compile-time-variable length.
So the question boils down to;
Q. How can I ensure m_fooFactors is an instantiation of an array of zeros of the known fixed-length so I can then populate it in the class constructor?
This EXAMPLE is a toy re. the m_fooFactors calculation, the actual calc is more complex, but gives you a flavor of my usage of the std::array as lookup-table.
I am using GCC and trying to make C++11 code.
I would be grateful for any help.

C wrapper for C++ class with stack allocation

Let's say we have a C++ library with a class like this:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
Typical usage of this class would include stack allocation:
TheClass object;
object.magic();
We need to create a C wrapper for this class. The most common approach looks like this:
struct TheClassH;
extern "C" struct TheClassH* create_the_class() {
return reinterpret_cast<struct TheClassH*>(new TheClass());
}
extern "C" void the_class_magic(struct TheClassH* self) {
reinterpret_cast<TheClass*>(self)->magic();
}
However, it requires heap allocation, which is clearly not desired for such a small class.
I'm searching for an approach to allow stack allocation of this class from C code. Here is what I can think of:
struct TheClassW {
char space[SIZEOF_THECLASS];
}
void create_the_class(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
new(cpp_self) TheClass();
}
void the_class_magic(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
cpp_self->magic();
}
It's hard to put real content of the class in the struct's fields. We can't just include C++ header because C wouldn't understand it, so it would require us to write compatible C headers. And this is not always possible. I think C libraries don't really need to care about content of structs.
Usage of this wrapper would look like this:
TheClassW object;
create_the_class(&object);
the_class_magic(&object);
Questions:
Does this approach have any dangers or drawbacks?
Is there an alternative approach?
Are there any existing wrappers that use this approach?
You can use placement new in combination of alloca to create an object on the stack. For Windows there is _malloca. The importance here is that alloca, and malloca align memory for you accordingly and wrapping the sizeof operator exposes the size of your class portably. Be aware though that in C code nothing happens when your variable goes out of scope. Especially not the destruction of your object.
main.c
#include "the_class.h"
#include <alloca.h>
int main() {
void *me = alloca(sizeof_the_class());
create_the_class(me, 20);
if (me == NULL) {
return -1;
}
// be aware return early is dangerous do
the_class_magic(me);
int error = 0;
if (error) {
goto fail;
}
fail:
destroy_the_class(me);
}
the_class.h
#ifndef THE_CLASS_H
#define THE_CLASS_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
class TheClass {
public:
TheClass(int me) : me_(me) {}
void magic();
int me_;
};
extern "C" {
#endif
size_t sizeof_the_class();
void *create_the_class(void* self, int arg);
void the_class_magic(void* self);
void destroy_the_class(void* self);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif // THE_CLASS_H
the_class.cc
#include "the_class.h"
#include <iostream>
#include <new>
void TheClass::magic() {
std::cout << me_ << std::endl;
}
extern "C" {
size_t sizeof_the_class() {
return sizeof(TheClass);
}
void* create_the_class(void* self, int arg) {
TheClass* ptr = new(self) TheClass(arg);
return ptr;
}
void the_class_magic(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->magic();
}
void destroy_the_class(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->~TheClass();
}
}
edit:
you can create a wrapper macro to avoid separation of creation and initialization. you can't use do { } while(0) style macros because it will limit the scope of the variable. There is other ways around this but this is highly dependent on how you deal with errors in the code base. A proof of concept is below:
#define CREATE_THE_CLASS(NAME, VAL, ERR) \
void *NAME = alloca(sizeof_the_class()); \
if (NAME == NULL) goto ERR; \
// example usage:
CREATE_THE_CLASS(me, 20, fail);
This expands in gcc to:
void *me = __builtin_alloca (sizeof_the_class()); if (me == __null) goto fail; create_the_class(me, (20));;
There are alignment dangers. But maybe not on your platform. Fixing this may require platform specific code, or C/C++ interop that is not standardized.
Design wise, have two types. In C, it is struct TheClass;. In C++, struct TheClass has a body.
Make a struct TheClassBuff{char buff[SIZEOF_THECLASS];};
TheClass* create_the_class(struct TheClassBuff* self) {
return new(self) TheClass();
}
void the_class_magic(struct TheClass* self) {
self->magic();
}
void the_class_destroy(struct TheClass* self) {
self->~TheClass();
}
C is supposed to make the buff, then create a handle from it and interact using it. Now usually that isn't required as reinterpreting pointer to theclassbuff will work, but I think that is undefined behaviour technically.
Here is another approach, which may or may not be acceptable, depending on the application specifics. Here we basically hide the existence of TheClass instance from C code and encapsulate every usage scenario of TheClass in a wrapper function. This will become unmanageable if the number of such scenarios is too large, but otherwise may be an option.
The C wrapper:
extern "C" void do_magic()
{
TheClass object;
object.magic();
}
The wrapper is trivially called from C.
Update 2/17/2016:
Since you want a solution with a stateful TheClass object, you can follow the basic idea of your original approach, which was further improved in another answer. Here is yet another spin on that approach, where the size of the memory placeholder, provided by the C code, is checked to ensure it is sufficiently large to hold an instance of TheClass.
I would say that the value of having a stack-allocated TheClass instance is questionable here, and it is a judgement call depending on the application specifics, e.g. performance. You still have to call the de-allocation function, which in turn calls the destructor, manually, since it is possible that TheClass allocates resources that have to be released.
However, if having a stack-allocated TheClass is important, here is another sketch.
The C++ code to be wrapped, along with the wrapper:
#include <new>
#include <cstring>
#include <cstdio>
using namespace std;
class TheClass {
public:
TheClass(int i) : x(i) { }
// cout doesn't work, had to use puts()
~TheClass() { puts("Deleting TheClass!"); }
int magic( const char * s, int i ) { return 123 * x + strlen(s) + i; }
private:
int x;
};
extern "C" TheClass * create_the_class( TheClass * self, size_t len )
{
// Ensure the memory buffer is large enough.
if (len < sizeof(TheClass)) return NULL;
return new(self) TheClass( 3 );
}
extern "C" int do_magic( TheClass * self, int l )
{
return self->magic( "abc", l );
}
extern "C" void delete_the_class( TheClass * self )
{
self->~TheClass(); // 'delete self;' won't work here
}
The C code:
#include <stdio.h>
#define THE_CLASS_SIZE 10
/*
TheClass here is a different type than TheClass in the C++ code,
so it can be called anything else.
*/
typedef struct TheClass { char buf[THE_CLASS_SIZE]; } TheClass;
int do_magic(TheClass *, int);
TheClass * create_the_class(TheClass *, size_t);
void delete_the_class(TheClass * );
int main()
{
TheClass mem; /* Just a placeholder in memory for the C++ TheClass. */
TheClass * c = create_the_class( &mem, sizeof(TheClass) );
if (!c) /* Need to make sure the placeholder is large enough. */
{
puts("Failed to create TheClass, exiting.");
return 1;
}
printf("The magic result is %d\n", do_magic( c, 232 ));
delete_the_class( c );
return 0;
}
This is just a contrived example for illustration purposes. Hopefully it is helpful. There may be subtle problems with this approach, so testing on your specific platform is highly important.
A few additional notes:
THE_CLASS_SIZE in the C code is just the size of a memory buffer in which
a C++'s TheClass instance is to be allocated; we are fine as long as
the size of the buffer is sufficient to hold a C++'s TheClass
Because TheClass in C is just a memory placeholder, we might just as
well use a void *, possibly typedef'd, as the parameter type in the
wrapper functions instead of TheClass. We would reinterpret_cast
it in the wrapper code, which would actually make the code clearer:
pointers to C's TheClass are essentially reinterpreted as C++'s TheClass anyway.
There is nothing to prevent C code from passing a TheClass* to the
wrapper functions that doesn't actually point to a C++'s TheClass
instance. One way to solve this is to store pointers to properly
initialized C++ TheClass instances in some sort of a data structure
in the C++ code and return to the C code handles that can be used to
look up these instances.
To use couts in the C++ wrapper we need to link with
the C++ standard lib when building an executable. For example, if
the C code is compiled into main.o and C++ into lib.o, then on
Linux or Mac we'd do gcc -o junk main.o lib.o -lstdc++.
It worth to keep each piece of knowledge in a single place, so I would suggest to make a class code "partially readable" for C. One may employ rather simple set of macro definitions to enable it to be done in short and standard words. Also, a macro may be used to invoke constructor and destructor at the beginning and the end of stack-allocated object's life.
Say, we include the following universal file first into both C and C++ code:
#include <stddef.h>
#include <alloca.h>
#define METHOD_EXPORT(c,n) (*c##_##n)
#define CTOR_EXPORT(c) void (c##_construct)(c* thisPtr)
#define DTOR_EXPORT(c) void (c##_destruct)(c* thisPtr)
#ifdef __cplusplus
#define CL_STRUCT_EXPORT(c)
#define CL_METHOD_EXPORT(c,n) n
#define CL_CTOR_EXPORT(c) c()
#define CL_DTOR_EXPORT(c) ~c()
#define OPT_THIS
#else
#define CL_METHOD_EXPORT METHOD_EXPORT
#define CL_CTOR_EXPORT CTOR_EXPORT
#define CL_DTOR_EXPORT DTOR_EXPORT
#define OPT_THIS void* thisPtr,
#define CL_STRUCT_EXPORT(c) typedef struct c c;\
size_t c##_sizeof();
#endif
/* To be put into a C++ implementation coce */
#define EXPORT_SIZEOF_IMPL(c) extern "C" size_t c##_sizeof() {return sizeof(c);}
#define CTOR_ALIAS_IMPL(c) extern "C" CTOR_EXPORT(c) {new(thisPtr) c();}
#define DTOR_ALIAS_IMPL(c) extern "C" DTOR_EXPORT(c) {thisPtr->~c();}
#define METHOD_ALIAS_IMPL(c,n,res_type,args) \
res_type METHOD_EXPORT(c,n) args = \
call_method(&c::n)
#ifdef __cplusplus
template<class T, class M, M m, typename R, typename... A> R call_method(
T* currPtr, A... args)
{
return (currPtr->*m)(args...);
}
#endif
#define OBJECT_SCOPE(t, v, body) {t* v = alloca(t##_sizeof()); t##_construct(v); body; t##_destruct(v);}
Now we can declare our class (the header is useful both in C and C++, too)
/* A class declaration example */
#ifdef __cplusplus
class myClass {
private:
int y;
public:
#endif
/* Also visible in C */
CL_STRUCT_EXPORT(myClass)
void CL_METHOD_EXPORT(myClass,magic) (OPT_THIS int c);
CL_CTOR_EXPORT(myClass);
CL_DTOR_EXPORT(myClass);
/* End of also visible in C */
#ifdef __cplusplus
};
#endif
Here is the class implementation in C++:
myClass::myClass() {std::cout << "myClass constructed" << std::endl;}
CTOR_ALIAS_IMPL(myClass);
myClass::~myClass() {std::cout << "myClass destructed" << std::endl;}
DTOR_ALIAS_IMPL(myClass);
void myClass::magic(int n) {std::cout << "myClass::magic called with " << n << std::endl;}
typedef void (myClass::* myClass_magic_t) (int);
void (*myClass_magic) (myClass* ptr, int i) =
call_method<myClass,myClass_magic_t,&myClass::magic,void,int>;
and this is a using C code example
main () {
OBJECT_SCOPE(myClass, v, {
myClass_magic(v,178);
})
}
It's short and working! (here's the output)
myClass constructed
myClass::magic called with 178
myClass destructed
Note that a variadic template is used and this requires c++11. However, if you don't want to use it, a number of fixed-size templates ay be used instead.
Here's how one might do it safely and portably.
// C++ code
extern "C" {
typedef void callback(void* obj, void* cdata);
void withObject(callback* cb, void* data) {
TheClass theObject;
cb(&theObject, data);
}
}
// C code:
struct work { ... };
void myCb (void* object, void* data) {
struct work* work = data;
// do whatever
}
// elsewhere
struct work work;
// initialize work
withObject(myCb, &work);
What I did in alike situation is something like:
(I omit static_cast, extern "C")
class.h:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
class.cpp
<actual implementation>
class_c_wrapper.h
void* create_class_instance(){
TheClass instance = new TheClass();
}
void delete_class_instance(void* instance){
delete (TheClass*)instance;
}
void magic(void* instance){
((TheClass*)instance).magic();
}
Now, you stated that you need stack allocation. For this I can suggest rarely used option of new: placement new. So you'd pass additional parameter in create_class_instance() that is pointing to an allocated buffer enough to store class instance, but on stack.
This is how I would solve the issue (basic idea is to let interprete C and C++ the same memory and names differently):
TheClass.h:
#ifndef THECLASS_H_
#define THECLASS_H_
#include <stddef.h>
#define SIZEOF_THE_CLASS 4
#ifdef __cplusplus
class TheClass
{
public:
TheClass();
~TheClass();
void magic();
private:
friend void createTheClass(TheClass* self);
void* operator new(size_t, TheClass*) throw ();
int x;
};
#else
typedef struct TheClass {char _[SIZEOF_THE_CLASS];} TheClass;
void create_the_class(struct TheClass* self);
void the_class_magic(struct TheClass* self);
void destroy_the_class(struct TheClass* self);
#endif
#endif /* THECLASS_H_ */
TheClass.cpp:
TheClass::TheClass()
: x(0)
{
}
void* TheClass::operator new(size_t, TheClass* self) throw ()
{
return self;
}
TheClass::~TheClass()
{
}
void TheClass::magic()
{
}
template < bool > struct CompileTimeCheck;
template < > struct CompileTimeCheck < true >
{
typedef bool Result;
};
typedef CompileTimeCheck< SIZEOF_THE_CLASS == sizeof(TheClass) >::Result SizeCheck;
// or use static_assert, if available!
inline void createTheClass(TheClass* self)
{
new (self) TheClass();
}
extern "C"
{
void create_the_class(TheClass* self)
{
createTheClass(self);
}
void the_class_magic(TheClass* self)
{
self->magic();
}
void destroy_the_class(TheClass* self)
{
self->~TheClass();
}
}
The createTheClass function is for friendship only - I wanted to avoid the C wrapper functions to be publicly visible within C++. I caught up the array variant of the TO, because I consider this better readable than the alloca approach. Tested with:
main.c:
#include "TheClass.h"
int main(int argc, char*argv[])
{
struct TheClass c;
create_the_class(&c);
the_class_magic(&c);
destroy_the_class(&c);
}

C++ templates and pre-process macro

Consider following code
#include <iostream>
using namespace std;
template<int I>
int myfunc()
{
#if I
return 1;
#else
return 2;
#endif
};
int main()
{
cout<<myfunc<0>()<<endl;
cout<<myfunc<1>()<<endl;
}
But the output is
2
2
The motivation to do this is following:
I have an algorithm, which needs to be implemented in both double and fixed point. One solution is to use a head file to define data type based on macro flag, for example,
#ifdef __DOUBLE__
typedef double InputType;
.... // a lot of other types
typedef double OutputType;
#else //Fixed Point
typedef int InputType;
... // a lot of other types, which are matching with "__DOUBLE__" section
typedef int OutputType;
The drawback of this type of solution is that you can't compare the two implementations at the runtime. You have to set the macro accordingly twice, compile twice, and run twice, and then compare the collected data. Ideally, I would like to have a template function or template class with a nontype parameter, which allows me to switch between implementations
Any other methodology can achieve the similar goal (comparing two implementation at run-time) is also welcome!
Thanks
Option: Template Specialization
You can specialize templates to allow for separate implementations. Template specializations can de done for classes as well. Consider:
template<typename T>
void foo(T) {
//general implementation
}
template<>
void foo(double d) {
//do something special for doubles
}
template<>
void foo(float f) {
//do something else for floats
}
Option: Enum of types
This is similar to OpenGL. Something like this:
enum MyTypes {FLOAT, DOUBLE};
void foo(MyType _m) {
//do some generic stuff
switch(_m) {
case FLOAT:
//do something for float
break;
case DOUBLE:
//do something else for float
break;
default:
//runtime error
}
//do some other stuff
}
But it takes a parameter into the function instead of a template argument.

Can you use assert to test type defintions in C++?

Can I use assert to enforce type definitions. Suppose there is a variable, double d, how can you use assert to assert that d is a double? If assert is not applicable (which I am betting isn't), is there another option? I am specifically looking to test for implicit type casting during debugging, while benefiting from the functionality of assert and #define NDEBUG.
P.S
Obviously I would want to use this for any type definition, just using double as an example here. The solution should be cross platform compatible and be compatible with C++03.
I like to add error checking to my class setters. For example, suppose there is a class, MyClass, with a private member variable, x:
void MyClass::setX(double input)
{
// assert x is double
x = input;
}
It's really a compile time check, so you should use static asserts for this.
Here is an example using boost's static asserts and type traits.
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
template<typename T>
void some_func() {
BOOST_STATIC_ASSERT( (boost::is_same<double, T>::value) );
}
TEST(type_check) {
some_func<double>();
}
I assume you mean in terms of a template anyway.
You can use the == operator defined in the type_info class to test for a specific type definition.
#include <assert.h>
#include <iostream>
#include <typeinfo>
int main ()
{
double a = 0;
std::cout << typeid(a).name() << std::endl;
assert(typeid(a)==typeid(double));
assert(typeid(a)==typeid(int)); // FAIL
}
Or borrowing from another SO answer using templates and try/catch:
#include <assert.h>
#include <iostream>
#include <typeinfo>
template <typename X, typename A>
inline void Assert(A assertion)
{
if( !assertion ) throw X();
}
#ifdef NDEBUG
const bool CHECK_ASSERT = false;
#else
const bool CHECK_ASSERT = true;
#endif
struct Wrong { };
int main ()
{
double a = 0;
std::cout << typeid(a).name() << std::endl;
assert(typeid(a)==typeid(double));
Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(double));
try
{
//assert(typeid(a)==typeid(int)); // FAIL and Abort()
Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(int)); // FALL
}
catch (Wrong)
{
std::cerr <<"Exception, not an int" <<std::endl;
}
}
You should be able to compare using std::is_same and using decltype. You can even use std::static_assert to move the check to compile time. I've seen it happen in libc++ :)
Note these are C++11 features, so you'll need to have a compiler that supports decltype
Given the current definition of the code, a way to check at compile time whether both are of the same type is:
template< typename T, typename U >
void assert_same_type( T const&, U const& )
{
int error[ sizeof( T ) ? -1 : -2 ]; // error array of negative size, dependent on T otherwise some implementations may cause an early error message even when they shouldn't
}
template< typename T >
void assert_same_type( T&, T& ){}
void MyClass::setX(double input)
{
assert_same_type( x, input ); // If the fallback case is instantiated then a compile time error will arise of trying to declare an array of negative size.
x = input;
}
You can create a template function, then overload the argument type for double like this:
#include <cassert>
template<class T>
bool is_double(T) { return false; }
bool is_double(double) { return true; }
int main() {
int i = 1;
double d = 3.14;
assert( is_double(d) );
assert( is_double(i) ); // fails
}
That would give a run-time error. You can generate a compile time error by simply defining a function that takes a double reference:
void is_double(double&) { }
void MyClass::setX(double input)
{
is_double(x); // assert x is double
x = input;
}