/*****************************************************************************

        LockFreeStack.h
        Author: Laurent de Soras, 2011

The object is placed in a cell which is sent to the stack. The cell is NOT
copied during the process of push/pop and therefore is not kept by the stack.
Only its link is changed.

It is to the user's responsibility to handle the cell memory and to keep it
safe until the cell is popped.

It has also to keep the cell's memory location valid until ALL the reading
clients terminate their operations, because the pop() operation may be reading
the next pointer of a cell which as been already popped by another reader.

Template parameters:

- T: type of the contained objects.

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

*Tab=3***********************************************************************/



#pragma once
#if ! defined (conc_LockFreeStack_HEADER_INCLUDED)
#define	conc_LockFreeStack_HEADER_INCLUDED



/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include "conc/AtomicPtrIntPair.h"
#include "conc/LockFreeCell.h"
#include "fstb/SingleObj.h"



namespace conc
{



template <class T>
class LockFreeStack
{

/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

public:

	typedef	T	ValueType;
	typedef	LockFreeCell <T>	CellType;

	               LockFreeStack ();
	virtual        ~LockFreeStack () = default;

	void           push (CellType &cell) noexcept;
	CellType *     pop () noexcept;



/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

protected:



/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:

	fstb::SingleObj <AtomicPtrIntPair <CellType> >
	               _head_ptr_ptr;



/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

private:

	               LockFreeStack (const LockFreeStack <T> &other)     = delete;
	               LockFreeStack (LockFreeStack <T> &&other)          = delete;
	LockFreeStack <T> &
	               operator = (const LockFreeStack <T> &other)        = delete;
	LockFreeStack <T> &
	               operator = (LockFreeStack <T> &&other)             = delete;
	bool           operator == (const LockFreeStack <T> &other) const = delete;
	bool           operator != (const LockFreeStack <T> &other) const = delete;

};	// class LockFreeStack



}	// namespace conc



#include "conc/LockFreeStack.hpp"



#endif	// conc_LockFreeStack_HEADER_INCLUDED



/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
