Sign in to follow this  
Dragon_Strike

problems with mpl::inherit_linearly *solved

Recommended Posts

Dragon_Strike    264
im havin some issues with mpl::inherit_linearly
template <typename T> struct assoc_map{	typedef std::map<boost::shared_ptr<T>, boost::shared_ptr<T>> type;};

// The following works
struct Assoc : public assoc_map<Camera>::type, public assoc_map<Geometry>::type, public assoc_map<Material>::type, public assoc_map<Mesh>::type, public assoc_map<Image>::type{}; 

// This doesnt work
//typedef boost::mpl::inherit_linearly<TList, boost::mpl::inherit<assoc_map<boost::mpl::_2>::type, boost::mpl::_1>>::type Assoc;






on the one that doesnt work i get the following error: error C2440: 'static_cast' : cannot convert from 'drone::scene::StateReadWriteBuffer::Assoc' to 'std::map<_Kty,_Ty> &' but i dont see what the differance is between the two? how do i fix this? here is the full source
#pragma once

#include <set>
#include <map>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>

#include "../Library/Identifiable.hpp"

#include "../Library/SPSCLockFreeBuffer.hpp"
#include "../Library/Synchronize.hpp"
#include "../Library/Utils.hpp"

namespace drone
{
	namespace scene
	{
		class State : private boost::noncopyable
		{			
			typedef boost::mpl::vector<Camera, Geometry, Material, Mesh, Image> TList;			
			typedef boost::mpl::inherit_linearly<TList, boost::mpl::inherit<std::set<boost::shared_ptr<boost::mpl::_2>, IDCompare>, boost::mpl::_1>>::type Buffer;

			template <typename T> struct id_set{ typedef std::set<boost::shared_ptr<T>, IDCompare> type;};	

			Buffer buffer;	

			CameraPtr activeCamera;
					
		public:						

			template <typename T>	    typename id_set<T>::type& Get()		 {	return static_cast<typename id_set<T>::type&>(buffer);		}
			template <typename T> const typename id_set<T>::type& Get() const {	return static_cast<const typename id_set<T>::type&>(buffer);	}

			template<typename T> 
			boost::shared_ptr<T> Find(const std::string& id) const
			{
				boost::shared_ptr<T> dummy(new T(id)); // TODO: fix hack 
				id_set<T>::type::const_iterator it = Get<T>().find(dummy);
				if(it == Get<T>().end())
					return boost::shared_ptr<T>();
				 
				return *it;
			}

			const CameraPtr ActiveCamera() const {	return activeCamera;	}
			CameraPtr		ActiveCamera()		 {	return activeCamera;	}

			void ActiveCamera(CameraPtr camera)	 {	activeCamera = camera;	}
		};

		class StateReadWriteBuffer : private boost::noncopyable
		{
			typedef boost::mpl::vector<Camera, Geometry, Material, Mesh, Image> TList;
			template <typename T> struct id_set{ typedef std::set<boost::shared_ptr<T>, IDCompare> type;};
			template <typename T> struct assoc_map{	typedef std::map<boost::shared_ptr<T>, boost::shared_ptr<T>> type;};

			struct Assoc : public assoc_map<Camera>::type, public assoc_map<Geometry>::type, public assoc_map<Material>::type, public assoc_map<Mesh>::type, public assoc_map<Image>::type{};

			//typedef boost::mpl::inherit_linearly<TList, boost::mpl::inherit<assoc_map<boost::mpl::_2>::type, boost::mpl::_1>>::type Assoc;

			struct Commiter
			{
				//Commiter(){}
				Commiter(Assoc& assoc) : assoc_(assoc){}

				mutable core::SPSCLockFreeQueue<boost::function<void()>> msgQueue;

				Assoc& assoc_;

			    template <typename T>
				void operator()(utils::wrap<T>)
				{
					utils::for_all(static_cast<assoc_map<T>::type&>(assoc_), boost::bind(&Commiter::Synchronize<assoc_map<T>::type::value_type>, this, _1));
				}

				template <typename T>
				void Synchronize(T& pair)
				{
					boost::function<void()> func = pair.first->SyncObject(pair.second);
					if(func)
						Push(func);
				}

				void Push(boost::function<void()> func)
				{
					msgQueue.Push(func);
				}

				void Apply() const
				{
					boost::function<void()> func;
					while(msgQueue.Pop(func))
						func();
				}
			};

		public:			
			//typedef boost::mpl::inherit_linearly<TList, boost::mpl::inherit<assoc_map<boost::mpl::_2>::type, boost::mpl::_1>>::type Assoc;
			
			Assoc assoc;

			Commiter commiter;

			State readState;
			State writeState;

			StateReadWriteBuffer() : commiter(assoc){}

			template <typename T>
			boost::shared_ptr<T> Add(boost::shared_ptr<T> write)
			{
				boost::shared_ptr<T> read(new T(*write));	

				writeState.Get<T>().insert(write);
				commiter.Push(boost::bind(&id_set<T>::type::insert, &readState.Get<T>(), read));

				static_cast<assoc_map<T>::type&>(assoc).insert(std::make_pair(write, read));

				return write;
			}

			template<typename T> boost::shared_ptr<T>		Write(const std::string& id)	  {	return writeState.Find<T>(id);	}			
			template<typename T> const boost::shared_ptr<T> Read(const std::string& id) const {	return readState.Find<T>(id);	}

			void Commit()
			{
				boost::mpl::for_each<TList, utils::wrap<boost::mpl::_1>>(boost::ref(commiter));

				assoc_map<Camera>::type::const_iterator it = static_cast<assoc_map<Camera>::type&>(assoc).find(writeState.ActiveCamera());
				if(it != static_cast<assoc_map<Camera>::type&>(assoc).end())
					commiter.Push(boost::bind(&State::ActiveCamera, &readState, it->second));
			}

			const State& Read() const
			{
				commiter.Apply();
				return readState;
			}

			State& Write()
			{
				return writeState;
			}			
		};

	}
}






if u have any suggestion on how i can make the code more readable please tell... [Edited by - Dragon_Strike on May 4, 2009 6:32:51 PM]

Share this post


Link to post
Share on other sites
Dmytry    1151
"but i dont see what the differance is between the two?"
I think inherit_linearly does something like that:
class root{
}
class a: public root,t0{
}
class b: public a,t1{
}
class c: public b,t2{
}
...
and returns last in sequence. You cant inherit from all at once in template.

"if u have any suggestion on how i can make the code more readable please tell..."
Keep it simple. Your code, from what I can see, actually does almost nothing. Why do you need that strange multiple inheritance abuse? When core code has to know all types (Camera, Geometry, Material, Mesh...) , that means there is too much coupling between core code and those . Core code shouldn't know it, and should not be changed when you add one more type.

Boost is good for two things: wasting a lot of time on even the most trivial problems, and writing a lot of code that looks impressive, generic, and complicated but actually does very little and is very unflexible. And I'm being generous; some would say that it is just 2 facets of one thing.
There is very few useful things in boost; and generally very few professional projects use advanced features of boost (I am excluding those projects that do not complete, counting only those that were deployed / generated revenue).

Look, this thread makes second result in google search for inherit_linearly, and first is the documentation. This should be quite good indicator of (lack of) usefulness of inherit_linearly.

For productive metaprogramming, you need programming language that does actually support metaprogramming (preferably using roughly same syntax for compile-time type expressions as for runtime code), not language which, by historical accident, happens to have turing complete macro-ish system never intended for anything but the most rudimentary metaprogramming, and lacking even the most rudimentary ability to locate bugs in "meta programs".

Share this post


Link to post
Share on other sites
Dragon_Strike    264
Quote:
Original post by Dmytry
"but i dont see what the differance is between the two?"
I think inherit_linearly does something like that:
class root{
}
class a: public root,t0{
}
class b: public a,t1{
}
class c: public b,t2{
}
...
and returns last in sequence. You cant inherit from all at once in template.

"if u have any suggestion on how i can make the code more readable please tell..."
Keep it simple. Your code, from what I can see, actually does almost nothing. Why do you need that strange multiple inheritance abuse? When core code has to know all types (Camera, Geometry, Material, Mesh...) , that means there is too much coupling between core code and those . Core code shouldn't know it, and should not be changed when you add one more type.

Boost is good for two things: wasting a lot of time on even the most trivial problems, and writing a lot of code that looks impressive, generic, and complicated but actually does very little and is very unflexible. And I'm being generous; some would say that it is just 2 facets of one thing.
There is very few useful things in boost; and generally very few professional projects use advanced features of boost (I am excluding those projects that do not complete, counting only those that were deployed / generated revenue).

Look, this thread makes second result in google search for inherit_linearly, and first is the documentation. This should be quite good indicator of (lack of) usefulness of inherit_linearly.

For productive metaprogramming, you need programming language that does actually support metaprogramming (preferably using roughly same syntax for compile-time type expressions as for runtime code), not language which, by historical accident, happens to have turing complete macro-ish system never intended for anything but the most rudimentary metaprogramming, and lacking even the most rudimentary ability to locate bugs in "meta programs".


well after reconsidering my design i have to agree with you... my attempt to make the code shorter and with less duplication has become counter productive... ive rewritten it...

thx for the answer

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this