By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,312 Members | 1,850 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,312 IT Pros & Developers. It's quick & easy.

Interfaces and their implementations, is this code legal/correct?

P: n/a
I am a basically a life-long Win32 C programmer specializing in high-end
winsock servers.

Before I dive into portable C++ programming, I wanted to code up an example
of what I thought would be a workable Collection template library. The idea
is to design API's that operate on interfaces, and provide
multi-implementations to that "single" API. C++ Interfaces and
Implementations, seems to behave like Win32 COM objects?

Please look over the following code sketch, and point out ALL of the flaws
that render it non-portable and/or non-std:

;)
Interfaces.cpp
--------------------
#ifndef NULL
# define NULL 0
#endif
// Collection objects
namespace Collections
{
// Forwards
template< typename T > class ICollection;
template< typename T > class IIterator;
template< typename T > class TNode;
template< typename T > class TStack;


// *** Interfaces ***
// The collection interface
template< typename T >

class ICollection
{

public:

virtual ~ICollection() {}

virtual void Push( T const* pObj, int iTimeout = 0 ) = 0;

virtual T* Pop( int iTimeout = 0 ) = 0;

virtual bool Pop( T const* pObj, int iTimeout = 0 ) = 0;

virtual IIterator< T >* RequestIterator() = 0;

virtual void ReleaseIterator( IIterator< T >* pIterator ) = 0;

};
// The iterator interface
template< typename T >

class IIterator
{

public:

// RAII
class CGuard
{

public:

CGuard( IIterator< T >* pIterator ) : m_pIterator( pIterator ) {}

~CGuard() { m_pIterator->GetCollection()->ReleaseIterator(
m_pIterator ); };
public:

IIterator< T >* operator ->() { return m_pIterator; }
private:

IIterator< T >* m_pIterator;

};
public:

virtual ~IIterator() {}

virtual void Next() = 0;

virtual void Prev() = 0;

virtual void Front() = 0;

virtual void Back() = 0;

virtual bool Eof() = 0;

virtual bool Bof() = 0;

virtual T* GetObj() = 0;

virtual ICollection< T >* GetCollection() = 0;

};


// *** Implmentation ***
// The collection node
template< typename T >

class TNode
{

public:

TNode( T const* pObj = NULL ) : m_pNext( NULL ), m_pObj( pObj ) {}
public:

TNode< T >* m_pNext;

T const* m_pObj;

};
// A stack object
template< typename T >

class TStack : public ICollection< T >
{

class CIterator;
private:

friend class CIterator;

class CIterator : public IIterator< T >
{

public:

CIterator( TStack< T >& Stack )
: m_Stack( Stack ),
m_pCurrent( NULL ),
m_pNext( NULL ),
m_pPrev( NULL ) {}
public:

void Next() {}

void Prev() {}

void Front() {}

void Back() {}
bool Eof()
{
return ( m_pCurrent && m_pCurrent->m_pNext ) ? true : false;
}
bool Bof()
{
return ( m_Stack.m_pFront == m_pCurrent ) ? true : false;
}
T* GetObj()
{
return ( m_pCurrent ) ? const_cast< T* >( m_pCurrent->m_pObj ) :
NULL;
}
ICollection< T >* GetCollection() { return &m_Stack; }
private:

TStack< T >& m_Stack;

TNode< T >* m_pCurrent;

TNode< T >* m_pNext;

TNode< T >* m_pPrev;

};
public:

void Push( T const* pObj, int iTimeout = 0 )
{

}
T* Pop( int iTimeout = 0 )
{
return NULL;
}
bool Pop( T const* pObj, int iTimeout = 0 )
{
return false;
}
IIterator< T >* RequestIterator()
{
return new CIterator( *this );
}
void ReleaseIterator( IIterator< T >* pIterator )
{
delete pIterator;
}
private:

TNode< T >* m_pFront;

};
}
// Test object
class CTest
{

public:

CTest() : m_Val1( 0 ) {}

public:

long m_Val1;

};
int main()
{
// Get the ICollection interface
Collections::ICollection< CTest >* pCol
= new Collections::TStack< CTest >;

{
// Get the ICollection's IIterator interface
Collections::IIterator< CTest >::CGuard
pIterator( pCol->RequestIterator() );
}

delete pCol;

return 0;
}
Thank you! =)

P.S.

I will be implementing some very fast, portable, lock-free algo's that will
use the interfaces posted here. If your interested I can post the code when
it is finished.

--
The designer of the experimental, SMP and HyperThread friendly, AppCore
library.

http://AppCore.home.comcast.net
Jul 19 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Check out my lock-free pthread semaphore:

http://appcore.home.comcast.net/pthreads/lfsema.cpp

http://appcore.home.comcast.net/pthreads/lfsema.h

This algo. totally skips kernel calls under contention.

Do a performance test, compare my semaphore to the pthread equivalent. Its
not even funny how much better the lock-free algo is.

Enjoy!

--
The designer of the experimental, SMP and HyperThread friendly, AppCore
library.

http://AppCore.home.comcast.net
Jul 19 '05 #2

P: n/a
DOH!

I you would need this in order to compile the semaphore:

http://appcore.home.comcast.net/pthreads/atomic.h

x86 SMP Compatible.
Jul 19 '05 #3

P: n/a
> Uhm, yes: try specific questions instead of "do this work for
me".
I apologize.

* Submit the code to the online Comeau compiler, it's one of the
most standard-conforming around.
Nice. So most compiler portability questions can be skipped, as long as the
code in question compiled without warning in a "strictly conforming"
compiler?

* Use smart-pointers such as std::auto_ptr and boost::shared_ptr
instead of raw C++ pointers.


I was thinking of a templated smart pointer interface, IAutoPtr.

So I can use one reference counted interface, and use it for C pointers and
COM's IUnknown interface.

Does that sound workable?
P.S.

How portable is the _asm keyword and 64-bit integers ( __int64 && long
long ) among popular c++ compilers?

My algos rely on a tiny bit of assembly.

--
The designer of the experimental, SMP and HyperThread friendly, AppCore
library.

http://AppCore.home.comcast.net
Jul 19 '05 #4

P: n/a
On Thu, 28 Aug 2003 22:58:25 GMT, "SenderX" <xx*@xxx.xxx> wrote:
Uhm, yes: try specific questions instead of "do this work for
me".
I apologize.

* Submit the code to the online Comeau compiler, it's one of the
most standard-conforming around.


Nice. So most compiler portability questions can be skipped, as long as the
code in question compiled without warning in a "strictly conforming"
compiler?


No, but error- and warning-free compilation with a compiler such as Comeau
is a good indication that the code is practically clean -- if it weren't,
then the chances are near certainty that the compiler would catch something.

But the only way to ensure portability is to (1) design and code for it,
(2) compile with the relevant compilers and (3) test on the relevant systems.

Systematically.

* Use smart-pointers such as std::auto_ptr and boost::shared_ptr
instead of raw C++ pointers.


I was thinking of a templated smart pointer interface, IAutoPtr.

So I can use one reference counted interface, and use it for C pointers and
COM's IUnknown interface.

Does that sound workable?


Not immediately. COM reference counting keeps the reference count in each
referred object, ordinary C++ smart-pointers keep the count in the pointer
object or in a shared helper object. Generally, nail => hammer, screw =>
screwdriver, and so on.

How portable is the _asm keyword
Not portable at all.

and 64-bit integers ( __int64 && long long ) among popular c++ compilers?
Not at all, but in C99 (and possibly future C++0x) it's another story.
My algos rely on a tiny bit of assembly.


Wrap it behind a clean C++ interface.

Jul 19 '05 #5

P: n/a
> No, but error- and warning-free compilation with a compiler such as Comeau
is a good indication that the code is practically clean
I got a "compile succeeded" using strict mode. So I am currently on the
correct path...

But the only way to ensure portability is to (1) design and code for it,
(2) compile with the relevant compilers and (3) test on the relevant systems.
Systematically.
Yep. ;(

How portable is the _asm keyword
Damn. Any special tricks to get assembly code to compile across different
compilers? ;)

and 64-bit integers ( __int64 && long long ) among popular c++ compilers?
Not at all, but in C99 (and possibly future C++0x) it's another story.


Mmmk.

My algos rely on a tiny bit of assembly.


Wrap it behind a clean C++ interface.


That would allow for a single interface that implements varying assembly
code specific to different processors.

// Interfaces

class IAtomic
-- CompareAndSwap(...) = 0;
-- ExchangeAdd(...) = 0;
// Specific processor implmenataions
class CIA32Atomic : public IAtomic
{
...
};
class CIA64Atomic : public IAtomic
{
...
};
class CPowerPCAtomic : public IAtomic
{
...
};
class CPowerPC64Atomic : public IAtomic
{
...
};
class CAMD64Atomic : public IAtomic
{
...
};

My lock-free code has to be portable across compiler, platform, and
processor. I think C++ and this group can help me.

Thanks.

--
The designer of the experimental, SMP and HyperThread friendly, AppCore
library.

http://AppCore.home.comcast.net
Jul 19 '05 #6

P: n/a
On Fri, 29 Aug 2003 00:12:10 GMT, "SenderX" <xx*@xxx.xxx> wrote:
>How portable is the _asm keyword


Damn. Any special tricks to get assembly code to compile across different
compilers? ;)


The usual "trick" is to write the assembly in -- assembly.

Then link it into the application.

E.g., parts of the C++ runtime library, for most any compiler, is
implemented that way.

Jul 19 '05 #7

P: n/a
In article <lOv3b.287479$Ho3.39520@sccrnsc03>, SenderX <xx*@xxx.xxx> wrote:
* Submit the code to the online Comeau compiler, it's one of the
most standard-conforming around.


Nice. So most compiler portability questions can be skipped,
as long as the code in question compiled without warning in
a "strictly conforming" compiler?


Use one of the "zillion" non-strictly conforming modes
of Comeau then if that is your concern. :)
--
Greg Comeau/4.3.3:Full C++03 core language + more Windows backends
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Jul 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.