Newer
Older
Import / projects / Gameloft / glwebtools / include / glwebtools / serialization / glwebtools_attributeformatter.h
#pragma once
#ifndef _GLWEBTOOLS_ATTRIBUTEFORMATTER_INCLUDED_
#define _GLWEBTOOLS_ATTRIBUTEFORMATTER_INCLUDED_

#include <string>
#include <vector>
#include <list>

#include <glwebtools/serialization/glwebtools_typetraits.h>

namespace glwebtools
{
	//! Specialize this traits for a class if it has functions begin() and end() and typedef iterator
	template <typename GLWEBTOOLS_T>
	struct IsList : glwebtools::FalseType
	{
	};

	template <class GLWEBTOOLS_T, class Allocator>
	struct IsList<std::vector<GLWEBTOOLS_T, Allocator> > : glwebtools::TrueType
	{
	};

	template <class GLWEBTOOLS_T, class Allocator>
	struct IsList<std::list<GLWEBTOOLS_T, Allocator> > : glwebtools::TrueType
	{
	};

	//! Specialize this traits for a class if it has functions getMinValue() and getMaxValue().
	template <typename GLWEBTOOLS_T>
	struct IsRange : glwebtools::FalseType
	{
	};

	//! Functor used to format attributes of requests to string 
	/*! Default Generic formatter. 
	*/
	class AttributeFormatter
	{
	public:
		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		template <typename VALUE>
		std::string operator()(VALUE value) const
		{
			return ListToString(value);
		}

		/*! Equality operator
		*/	
		bool operator==(const AttributeFormatter&) const
		{
			return true;
		}

	public:
		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(bool value);

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(int value);

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(unsigned int value);

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(long long value);

		/*! Formats value to string 
		\param value The value to format
		\param precision The decimal precision to be used when formatting the float value
		\return The formatted string 
		*/			
		static std::string ToString(float value, int precision=2);

		/*! Formats value to string 
		\param value The value to format
		\param precision The decimal precision to be used when formatting the float value
		\return The formatted string 
		*/			
		static std::string ToString(double value, int precision=2);

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(const char* value)
		{
			return value;
		}

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/			
		static std::string ToString(const std::string& value)
		{
			return value;
		}

		template <typename VALUE>
		static std::string ToString(VALUE value)
		{
			Assert("Cannot format unknown type.");
			return "Error: Cannot format unknown type.";
		}

	protected:
		static void Assert(const std::string& message);


	protected:
		template <typename VALUE>
		static std::string ListToString(VALUE value)
		{
			typename IsList<VALUE>::type islist;
			return ListToString(value, islist);
		}

		template <typename VALUE>
		static std::string ListToString(VALUE value, /*IsList*/glwebtools::FalseType)
		{
			typename IsRange<VALUE>::type isrange;
			return RangeToString(value, isrange);
		}

		template <typename VALUE>
		static std::string ListToString(VALUE value, /*IsList*/glwebtools::TrueType)
		{
			std::string str;

			typedef typename VALUE::iterator iterator;
			for (iterator it = value.begin(); it != value.end(); ++it)
			{
				if (it != value.begin())
					str+=",";

				str += ListToString(*it);
			}

			return str;
		}

		template <typename VALUE>
		static std::string RangeToString(VALUE value, /*IsRange*/glwebtools::FalseType)
		{
			return ToString(value);
		}

		template <typename VALUE>
		static std::string RangeToString(VALUE value, /*IsRange*/glwebtools::TrueType)
		{
			return ToString(value.getMinValue())+"-"+ToString(value.getMaxValue());
		}
	};

	//! Functor used to format attributes of requests to string 
	/*! Formatter of float values, with a fixed precision. 
	*/
	template <int PRECISION>
	class FloatFormatter
	{
	public:
		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/	
		std::string operator()(float value) const
		{
			return m_formatter.ToString(value, PRECISION);
		}

		/*! Formats value to string 
		\param value The value to format
		\return The formatted string 
		*/	
		std::string operator()(double value) const
		{
			return m_formatter.ToString(value, PRECISION);
		}

		/*! Equality operator
		*/	
		bool operator==(const FloatFormatter<PRECISION>&) const
		{
			return true;
		}
	private:
		AttributeFormatter m_formatter;
	};
}// glwebtools

#endif // _GLWEBTOOLS_ATTRIBUTEFORMATTER_INCLUDED_