#include <iostream>
#include <vector>
using namespace std;
template< typename TBufferTypeFront, typename TBufferTypeBack = TBufferTypeFront>
class FrontBackBuffer {
// If <const * int , int&> --> this result in is_same< int , int >
// STATIC_ASSERT( std::is_same< RemoveModifiers<TBufferTypeFront>::type, typename RemoveModifiers<TBufferTypeFront>::type>::result )
public:
template <typename T>
struct MyRefTypes {
typedef T Org;
typedef T* Ptr;
typedef const T & Con;
typedef T& Ref;
typedef const T& CRef;
static inline Ptr getUnderlyingPtr(T& v) {
return &v;
}
static Ref getRef(T& v) {
return v;
}
};
//Specialization for Reference
template <typename T>
struct MyRefTypes<T&> {
typedef T Org;
typedef T* Ptr;
typedef T & Con;
typedef T& Ref;
typedef const T& CRef;
static inline Ptr getUnderlyingPtr(T& v) {
return &v;
}
static inline Ref getRef(T& v) {
return v;
}
};
//Specialization for const Reference
template <typename T>
struct MyRefTypes<const T&> {
typedef T Org;
typedef T* Ptr;
typedef const T & Con;
typedef const T& Ref;
typedef const T& CRef;
static inline Ptr getUnderlyingPtr(const T& v) {
return &const_cast<T&>(v);
}
static inline Ref getRef(const T& v) {
return v;
}
};
//Specialization for const
template <typename T>
struct MyRefTypes<const T> {
typedef T Org;
typedef T* Ptr;
typedef const T & Con;
typedef const T& Ref;
typedef const T& CRef;
static inline Ptr getUnderlyingPtr(const T& v) {
return &const_cast<T&>(v);
}
static inline Ref getRef(const T& v) {
return v;
}
};
//Specialization for pointers
template <typename T>
struct MyRefTypes<T*> {
typedef T* Ptr;
typedef T Org;
typedef T* Con;
typedef T& Ref;
typedef T* const CRef; //! note this is a pointer....
static inline Ptr getUnderlyingPtr(T* v) {
return v;
}
static inline Ref getRef(T* v) {
return *v;
}
};
//Specialization for const pointers
template <typename T>
struct MyRefTypes<const T*> {
typedef T Org;
typedef T* Ptr;
typedef const T* Con;
typedef const T& Ref;
typedef const T* const CRef; //! note this is a pointer....
static inline Ptr getUnderlyingPtr(const T* v) {
return const_cast<T*>(v);
}
static inline Ref getRef(const T* v) {
return *v;
}
};
typedef typename MyRefTypes<TBufferTypeFront>::Ref TBufferTypeFrontRef;
typedef typename MyRefTypes<TBufferTypeFront>::CRef TBufferTypeFrontCRef;
typedef typename MyRefTypes<TBufferTypeFront>::Con TBufferTypeFrontCon;
typedef typename MyRefTypes<TBufferTypeFront>::Org TBufferTypeFrontOrg;
typedef typename MyRefTypes<TBufferTypeFront>::Ptr TBufferTypeFrontPtr;
typedef typename MyRefTypes<TBufferTypeBack >::Ref TBufferTypeBackRef;
typedef typename MyRefTypes<TBufferTypeBack >::CRef TBufferTypeBackCRef;
typedef typename MyRefTypes<TBufferTypeBack >::Con TBufferTypeBackCon;
typedef typename MyRefTypes<TBufferTypeBack >::Org TBufferTypeBackOrg;
typedef typename MyRefTypes<TBufferTypeBack >::Ptr TBufferTypeBackPtr;
explicit FrontBackBuffer(
TBufferTypeFrontCon front,
TBufferTypeBackCon back):
m_Front(front),
m_Back(back)
{
m_pBack = MyRefTypes<TBufferTypeBack>::getUnderlyingPtr(m_Back);
m_pFront = MyRefTypes<TBufferTypeFront>::getUnderlyingPtr(m_Front);
};
~FrontBackBuffer()
{};
TBufferTypeFrontRef getFront() {
return *m_pFront;
}
TBufferTypeBackRef getBack() {
return *m_pBack;
}
void swap(){
TBufferTypeFrontPtr temp = m_pFront;
m_pFront = m_pBack;
m_pBack = temp;
}
private:
TBufferTypeFrontPtr m_pFront; ///< The pointer to front buffer
TBufferTypeBackPtr m_pBack; ///< The pointer to back buffer
TBufferTypeFront m_Front; ///< The front buffer
TBufferTypeBack m_Back; ///< The back buffer
};
typedef std::vector<float> GAGAType ;
int main() {
int front=10;
int back=3;
FrontBackBuffer< const int*, int & > buf1(&front, back);
buf1.getBack() = 4; // change from 3 to 4
// buf.getFront() = 5; NO! is const!
buf1.swap();
std::cout << buf1.getFront() << buf1.getBack() << std::endl;
//NOW getBack() and getFront() should return 4 and 10!
front = 1;
back= -1;
FrontBackBuffer<int &, int > buf2(front, back);
buf2.getBack() = 2;
buf2.getFront() = 3;
buf2.swap();
//NOW getBack() and getFront() should return 2 and 3!
std::cout << buf2.getFront() << buf2.getBack() << std::endl;
front = 1;
back= -1;
FrontBackBuffer<int, const int &> buf3(front, back);
//buf3.getBack() = 2; // IS CONST!!
buf3.getFront() = 3;
buf3.swap();
//NOW getBack() and getFront() should return -1 and 3!
std::cout << buf3.getFront() << buf3.getBack() << std::endl;
}