Pointer to class member function of template parameter - c++

Hi I have a problem to compile my class in XCode, gcc(Apple LLVM compiler 3.0)
I wrote class ContextSchedule it means class which encapsulates list of other class member functions and have no problem to compile it under MSVC++ 2005.
template<class T>
class C_ContextScheduler
{
public:
typedef void (T::*T_EventFunc)();
typedef std::map<u64, T_EventFunc> T_EventMap;
public:
//# c-tor
C_ContextScheduler(T & context) : m_Context(context), m_currentTick(0) {};
//# Schedule
//# funcPtr - pointer to function of class T
//# dellayTime in milliseconds - after dellayTime from now will be funcPtr called
void Schedule(T_EventFunc funcPtr, u32 dellayTime)
{
u64 callingTime = m_currentTick + dellayTime;
std::pair<int, bool> res = m_eventMap.insert(T_EventMap::value_type(callingTime, funcPtr));
SC_ASSERT(res.second);
} ...
Any ideas? Want preserve template way of this solution, thnx.

When the compiler compiles this template, T is not yet known. Therefore the exact type of T_EventFunc and T_EventMap is also not yet known and that compiler doesn't know that T_EventMap::value_type will end up being a type. To make this clear, use the typename keyword:
... = m_eventMap.insert(typename T_EventMap::value_type(callingTime, funcPtr));

Since you don't supply the error you are getting, we can only guess. And my guess is that the result of your insert-call is not correct.
According to this refernce, the return value of std::map::insert is std::pair<iterator, bool>. Are you sure the iterator is an int?

Related

Testing template to memory location to replace defines in embedded systems

In embedded systems, you often have a memory location which is not within the program memory itself but which points to some hardware registers. Most C SDKs provide these as #define statements. According to the following article, https://arne-mertz.de/2017/06/stepping-away-from-define/ one method of transitioning from #define statements (as used by C SDKs) to something more C++ friendly, is to create a class which forces reinterpret_cast to occur at runtime.
I am trying to go about this in a slightly different way because I want to be able to create "type traits" for the different pointers. Let me illustrate with an example.
#define USART1_ADDR 0x1234
#define USART2_ADDR 0x5678
template <typename T_, std::intptr_t ADDR_>
class MemPointer {
public:
static T_& ref() { return *reinterpret_cast<T_*>(ADDR_); }
};
class USART {
public:
void foo() { _registerA = 0x10; }
private:
uint32_t _registerA;
uint32_t _registerB;
};
using USART1 = MemPointer<USART, USART1_ADDR>;
using USART2 = MemPointer<USART, USART2_ADDR>;
template <typename USART_>
class usart_name;
template <>
class usart_name<USART1> {
public:
static constexpr const char* name() { return "USART1"; }
};
template <>
class usart_name<USART2> {
public:
static constexpr const char* name() { return "USART2"; }
};
Each USART "instance" in this example is its own, unique type so that I am able to create traits which allow compile-time "lookup" of information about the USART instance.
This actually seems to work, however, I wanted to create some test code as follows
static USART testUsart;
#define TEST_USART_ADDR (std::intptr_t)(&testUsart);
using TEST_USART = MemPointer<USART, TEST_USART_ADDR>;
Which fails with the following error:
conversion from pointer type 'USART*' to arithmetic type
'intptr_t' {aka 'long long int'} in a constant expression
I believe I understand the source of the problem based upon Why is reinterpret_cast not constexpr?
My question is, is there a way to make my MemPointer template work for test code like above as well?
EDIT
One solution is to have a separate class for each "instance" has follows
class USART1 : public USART {
public:
static USART& ref() { return *reinterpret_cast<USART*>(USART1_ADDR); }
};
class USART2 : public USART {
public:
static USART& ref() { return *reinterpret_cast<USART*>(USART2_ADDR); }
};
I would prefer some sort of template + using combination though so that I don't need to write a bunch of classes. But perhaps this is the only option.
is there a way to make my MemPointer template work for test code like above as well?
You could just stop insisting that the address be an intptr_t. You're going to cast it to a pointer anyway, so why not just allow any type for which that conversion exists?
template <typename T_, typename P, P ADDR_>
class MemPointer {
public:
static T_& ref() { return *reinterpret_cast<T_*>(ADDR_); }
};
using USART1 = MemPointer<USART, std::intptr_t, USART1_ADDR>;
using USART2 = MemPointer<USART, std::intptr_t, USART2_ADDR>;
static USART testUsart;
using TEST_USART = MemPointer<USART, USART*, &testUsart>;
Follow-up notes:
if this were for a library to be used by others, I'd consider adding a static_assert(std::is_trivial_v<T_>) inside MemPointer to catch annoying errors
there are a few potential issues around things like padding & alignment, but I assume you know what your particular embedded platform is doing
you should volatile-qualify your register members, or the whole object (eg. you can return std::add_volatile_t<T_>& from MemPointer::ref)
This is so the compiler knows that every write is an observable side-effect (ie, observable by the hardware even if your program never reads it back), and that every read may produce a different value (because the hardware can update it even if your program doesn't).

Why isn't my boost::multi_index modify() compiling?

I'm using boost::multi_index_container and am trying to get a modify operation working. My modification routine looks like this (roughly), using a function inner class:
void FooContainer::modifyAttribute(string key, int newValue) {
struct ModifyFunc {
int val;
ModifyFunc(int val): val(val) {}
void operator()(Foo &f) {
foo.val = val;
}
};
StorageContainer::index<keyTag>::type &idx = mContainer.get<keyTag>();
StorageContainer::index<keyTag>::type::iterator iter = idx.find(key);
idx.modify(iter, ModifyFunc(newValue));
}
When I try to compile this, I get a multi-page spew of compiler error like this (most of it omitted):
FooContainer.cpp:##: error: no matching function for call to [...]::modify([...]&, FooContainer::modifyAttribute(string,int)::ModifyFunc)’
What's wrong with this invocation and how can I make it work?
The problem is that function inner classes aren't recognized by the compiler as a valid typename for template parameters; it isn't obvious, but the multi_index_container::index<T>::type::modify method uses the type of the modify parameter as a template argument which is a detail normally hidden from view. However, look at its declaration in, for example, boost/multi_index/hashed_index.hpp:
template<typename Modifier>
bool modify(iterator position,Modifier mod)
The easy fix is to make the ModifyFunc struct not a function inner class; trivially, make it inner to FooContainer rather than to the FooContainer::modifyAttribute method. Of course, this also means that you can reuse the ModifyFunc class elsewhere, if it turns out you need it in more than one place.

C++ polymorphism with template interface

Timer.h:
template<class T>
class Timer {
public:
typedef T Units;
virtual Units get() = 0;
};
TimerImpl.h:
class TimerImpl: public Timer<long> {
public:
TimerImpl() {
}
~TimerImpl() {
}
long get();
};
FpsMeter.h(version 1):
template <class T>
class FpsMeter {
private:
Timer<T>* timer;
public:
FpsMeter (Timer<T>* timer) {
this->timer = timer;
}
...
};
This example works. But it does not look pretty.
Timer<long>* t = new TimerImpl();
FpsMeter<long>* f1 = new FpsMeter<long> (t);
Here there are a lot of extra template uses. How can I realize this idea of multy-type interface when the type is defined by the implementation and user class has not to define new type, it should use the type of the implementation.
If you don't mind a helper template function which always creates FpsMeter on the heap you could something like the following
template < class T >
FpsMeter<T> *make_FpsMeter( Timer<T> *timer ) {
return new FpsMeter<T>( timer );
}
Then creating a FpsMeter of the appropriate type is like so
FpsMeter<long> *f1 = make_FpsMeter( new TimerImpl() );
Or if you can use C++11 auto you'd get
auto f1 = make_FpsMeter( new TimerImpl() );
This is the best you can do in C++, as far as I know. FpsCounter needs to know the type T so that it knows which Timer<T> implementations it can accept. Your sample code can be made somewhat simpler:
FpsMeter<long>* f1 = new FpsMeter<long> (new TimerImpl());
...which at least gets you out of repeating the template type, but of course in that case FpsMeter must take responsibility for deleting the TimerImpl, ideally through an auto_ptr or such.
I'd question, too, whether you really need to vary the return value of get(). What sorts of values do you expect it to return, besides long?
Maybe you can take inspiration from the <chrono> library from C++11 (also available in boost). Or better yet, save yourself some time and just use it directly. It's efficient, safe, flexible, and easy to use.
If you want to use only timers based on implementation of machine timer (which should be defined at compilation stage for entire program I assume), i would simply use typedef and perhaps some preprocessor magic to get it right:
[...]
#if TIMER_LONG // Here you should somehow check what type is used on target platform.
typedef Timer<long> implTimer;
typedef FpsMeter<long> implFpsMeter;
#else // If eg. using double?
typedef Timer<double> implTimer;
typedef FpsMeter<double> implFpsMeter;
#fi
This should make user code unaware of actual typee used, as long it is using implTimer and implFpsMeter.
If you mean that some parts of code will use different TimerImpl then you should make your FpsMeter class polymorphic
class FpsMeter{
public:
virtual double fps()=0;
virutal void newFrame()=0;
[...]
//Class counts new frames and using internal timer calculates fps.
};
template <typename T>
class FpsMeterImpl: public FpsMeter{
TimerImpl<T>* timer;
public:
FpsMeterImpl(TimerImpl<T>* timer);
virtual double fps();
virutal void newFrame();
};

GCC Segfaults When `decltype` Used in Nested Lambda

I created a macro that conveniently builds lambda functions using which I can iterate through tensor objects in a library that I wrote. However, nesting these macros seemed to cause GCC to undergo an internal segmentation fault. Upon expanding the compiler's preprocessor output and going through some trial and error, I discovered that cause seems to be the use of decltype in the parameter list of a nested lambda function declared in the method of a class or struct. Below follows a minimal example using the standard library.
#include <iostream>
#include <type_traits>
template <class Iterator, class Func>
void for_each(const Iterator first, const Iterator last, Func func)
{
for (Iterator it = first; it != last; ++it) {
func(*it);
}
}
template <class T>
class helper
{
typedef typename T::size_type type;
};
template <class T>
class helper<T&>
{
typedef typename T::size_type type;
};
template <class T>
class helper<T*>
{
typedef typename T::size_type type;
};
struct bar
{
struct foo
{
typedef int size_type;
} foo_;
void test()
{
int arr[] = { 1, 2, 3 };
for_each(arr, arr + 3, [&](int i) {
/*
** XXX: The "typename ... type" segfaults g++!
*/
for_each(arr, arr + 3, [&](typename helper<decltype(foo_)>::type j) {
});
});
}
};
int main()
{
return 0;
}
Compiler Output:
$ g++ -Wall -std=c++0x nested_lambda.cpp
nested_lambda.cpp: In lambda function:
nested_lambda.cpp:42:56: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccqYohFA.out file, please attach this to your bugreport.
I initially opted to use decltype because an object is passed to a macro, and I need to extract the object's type. From the object's type, (T, T&, or T*), I'd use a traits class to pull T::size_type. size_type would then be the type of the lambda function parameters.
How can I circumvent this issue without having to use a typedef to declare the type of the lambda function parameter in advance? If you can think of some other solution that could easily be implemented in a macro (i.e. copied and pasted repeatedly in the parameter list of a lambda function), that would work too.
As a very rough workaround for those who may be experiencing similar issues, the best standard solution I could come up with involved having the macro declare a typedef in advance, concatenating GUID-like prefix (I personally recommend _qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_) and __LINE__ to generate some warbled nonsense for the typedef name. With all luck, this name will not clash with any other definitions.
To ensure that the same __LINE__ gets concatenated even when the warbled name is used for the lambda function parameter types, the warbled name will need to be generated by a macro that is initially passed a macro parameter, as in the code sample below.
#define _foo_GUID \
_qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_
#define _foo_MANGLE_IMPL2(a, b) \
a ## b
#define _foo_MANGLE_IMPL(a, b) \
_foo_MANGLE_IMPL2(a, b)
#define _foo_MANGLE(a) \
_foo_MANGLE_IMPL(_foo_GUID, a)
When passing _foo_MANGLE(__LINE__) as a macro parameter, please ensure that there is an extra level of indirection so that _foo_MANGLE(__LINE__) gets evaluated before it is used.
This bug is currently being addressed, and I think that it should be fixed soon.

Practices regarding wrapper for setDataBuffer (OCCI)

I have an OracleConnection class that uses the OCCI Oracle API to access the database. I now need to go fetch multiple rows of records from the database and this is done with the ResultSet::getDataBuffer(...) function of the API. This function takes a series of arguments, one of them being a big enum which defines the types of data can contain.
Obviously I don't want to strew my application code with Oracle API types, so other API's could be interchanged with this one. So my question is how would I best take this Type parameter in my function wrapper? Should I just create an enum and take only the types I will need or could templates help me here to map to the enum of OCCI in the OracleConnection class I have?
Occi setDataBuffer function:
void setDataBuffer(
unsigned int colIndex,
void *buffer,
Type type,
sb4 size = 0,
ub2 *length = NULL,
sb2 *ind = NULL,
ub2 *rc = NULL);
Type here is an enum that looks like this:
enum Type
{
OCCI_SQLT_CHR=SQLT_CHR,
OCCI_SQLT_NUM=SQLT_NUM,
OCCIINT = SQLT_INT,
OCCIFLOAT = SQLT_FLT,
OCCIBFLOAT = SQLT_BFLOAT,
OCCIBDOUBLE = SQLT_BDOUBLE,
OCCIIBFLOAT = SQLT_IBFLOAT,
OCCIIBDOUBLE = SQLT_IBDOUBLE,
OCCI_SQLT_STR=SQLT_STR,
OCCI_SQLT_VNU=SQLT_VNU,
OCCI_SQLT_PDN=SQLT_PDN,
OCCI_SQLT_LNG=SQLT_LNG,
OCCI_SQLT_VCS=SQLT_VCS,
.... (about 2x as many to go)
my wrapper looks as follows:
void setDataBuffer(unsigned int colIndex, void * buffer, unsigned long size = 0, int type /*use int or template or redefine own Type Enum?*/, unsigned short * length = NULL, signed short * ind = NULL, unsigned short * rc = NULL)
One option could be to make your function a template, and then use a traits class to convert the template type to the values representing the various Oracle types.
The traits class could look like this:
template <typename T>
struct oracle_type_traits;
template <> // create a specialization for each relevant type
struct oracle_type_traits<double> {
static const value = OCCIBDOUBLE // its value member should be the value you want to map to
};
Now, the following will give you the Oracle type id for a double:
oracle_type_traits<double>::value
and inside setDataBuffer<T>(...), you just check oracle_type_traits<T>::value to get the corresponding Oracle type ID.
From the POV of the users of your wrapper, the best would be if they would call either an overloaded function or a function (member) template that they pass an object to of the appropriate type and which will then magically do the right thing for that type. That is, the best would be to have a function getData(unsigned int colIndex, T&) for any type T your class (or the Oracle API) supports, which will find out the necessary buffer size, allocate the buffer, determine the right enum, and call the Oracle API function.
I'm sure you can work out most of the details, probably with the exception of how to map a type to the enum, so this is what I'll try to line out.
Basically, I see two possibilities for this, one of which (employing a compile-time list) is better suited if you have lots of types to support, while the other one (employing traits) needs to be used if there's more type-specific to this than just mapping a type to an enum.
The traits method is quite simple to use, but tedious if you have many types:
template<typename T>
struct get_data_buffer_traits;
template<>
struct get_data_buffer_traits<int> {
Type type OCCIINT;
};
template<>
struct get_data_buffer_traits<float> {
Type type OCCIBFLOAT;
};
You can then map the type passed to your template as T into the right enum value using get_data_buffer_traits<T>::type.
This traits template is also the place where you can put any other type-specific operation your generic data retrieval function might need (like converting between what's in the buffer and the actual type, if that isn't a straight-forward cast). If you don't have anything else to put into these traits, you could use a macro to make defining these easier:
#define DEFINE_GET_DATA_BUFFER_TRAITS(Type_,Enum_) \
template<> struct get_data_buffer_traits<Type_> { Type type Enum_; };
DEFINE_GET_DATA_BUFFER_TRAITS(int , OCCIINT );
DEFINE_GET_DATA_BUFFER_TRAITS(float, OCCIBFLOAT);
...
#undef DEFINE_GET_DATA_BUFFER_TRAITS
However, if that's the case, you might as well create a compile-time map that maps the two and search that (at compile-time) for the right enum value. If you don't have a template meta library at hand that provides this, here's the outline for an idea how to do that yourself:
// Beware, brain-compiled code ahead!
struct nil {};
template< typename HType
, Type HEnum
, class T >
struct set_data_buffer_type_map_node {
typedef HType head_type
enum { head_enum = HEnum };
typedef T tail_type;
};
typedef
set_data_buffer_type_map_node< int , OCCIINT
set_data_buffer_type_map_node< float, OCCIBFLOAT
...
nil
> > // either count or keep adding these until compiler accepts :)
set_data_buffer_type_map;
template< typename T, class Map >
struct getter {
// recurse towards tail
Type get_enum() { return getter<T,typename Map::tail_type>::get_enum(); }
};
template< typename T, Type HEnum, class Tail >
struct getter< T, set_data_buffer_type_map<T,HEnum,Tail> > {
// current node has T as HType
Type get_enum() { return set_data_buffer_type_map<T,HEnum,Tail>::head_enum; }
};
template< typename T, typename HType, Type HEnum, >
struct getter< T, set_data_buffer_type_map<T,HEnum,nil> > {
// no function here, so compile-time error
};
template< typename T>
Type get_type_enum()
{
return getter<T, set_data_buffer_type_map>::get_enum();
}
(Note: This is just an outline. I have not even attempted to compile it. )
I will suggest to go with enum option. Using it as template means your API users should have idea about all the types before which can be bit difficult. Using it as enum also give them as option to refer the enum and decide which SQL types suits the requirement.