root/trunk/0032_DynamicAny/DynamicAnyTest.cpp

User picture

Author: Setsu

Revision: 348 («Previous)


File Size: 7.9 KB

(June 16, 2010 11:57 UTC) Almost 2 years ago

DynamicAny

 
Show/hide line numbers
//
//  DynamicAnyTest.cpp
//
//  Created by Setsu on 6/16/10.
//  Copyright 2010 RoundSquare Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

//----------------------------------------
//	include
//----------------------------------------
#include <Poco/Logger.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/DynamicAny.h>
#include <Poco/TypeList.h>

#include <string>
#include <typeinfo>
#include <algorithm>

#include "ScopedLogMessage.h"

//----------------------------------------
//	const
//----------------------------------------
enum EMyType {	eTypeChar = 0
			,	eTypeInt8
			,	eTypeUInt8
			,	eTypeInt16
			,	eTypeUInt16
			,	eTypeInt32
			,	eTypeUInt32
			,	eTypeInt64
			,	eTypeUInt64
			,	eTypeFloat
			,	eTypeDouble
			,	eTypeString
			,	eTypeBool	};

const std::string kMyTypeName[] = {
				"char"
			,	"Poco::Int8"
			,	"Poco::UInt8"
			,	"Poco::Int16"
			,	"Poco::UInt16"
			,	"Poco::Int32"
			,	"Poco::UInt32"
			,	"Poco::Int64"
			,	"Poco::UInt64"
			,	"float"
			,	"double"
			,	"std::string"
			,	"bool"	};

const int kNumMyTypeKind = sizeof(kMyTypeName)/sizeof(kMyTypeName[0]);

//----------------------------------------
//	struct
//----------------------------------------
struct TestTypes
{
	char			c;
	Poco::Int8		i8;
	Poco::UInt8		u8;
	Poco::Int16		i16;
	Poco::UInt16	u16;
	Poco::Int32		i32;
	Poco::UInt32	u32;
	Poco::Int64		i64;
	Poco::UInt64	u64;
	float			f;
	double			d;
	std::string		s;
	bool			b;
};

//----------------------------------------
//	typedef
//----------------------------------------
typedef Poco::TypeListType<
	char
,	Poco::Int8
,	Poco::UInt8
,	Poco::Int16
,	Poco::UInt16
,	Poco::Int32
,	Poco::UInt32
,	Poco::Int64
,	Poco::UInt64
,	float
,	double
,	std::string
,	bool
	>::HeadType MyTypeList;

//----------------------------------------
//	TestDynamicAnyBase
//----------------------------------------
class TestDynamicAnyBase
{
public:
	TestDynamicAnyBase()
	{
	}
	virtual ~TestDynamicAnyBase()
	{
	}
	virtual std::string isNative(const char* typeidStr) = 0;
};

//----------------------------------------
//	TestDynamicAny
//----------------------------------------
template <EMyType N>
class TestDynamicAny : public TestDynamicAnyBase
{
	typedef typename Poco::TypeGetter<N, MyTypeList>::HeadType	MyType;

public:
	TestDynamicAny(TestTypes& dest, MyType src) : TestDynamicAnyBase()
	{
		Poco::DynamicAny a = src;

		a.convert(dest.i8);
		a.convert(dest.u8);
		a.convert(dest.i16);
		a.convert(dest.u16);
		a.convert(dest.i32);
		a.convert(dest.u32);
		a.convert(dest.i64);
		a.convert(dest.u64);
		a.convert(dest.f);
		a.convert(dest.d);
		a.convert(dest.b);
		a.convert(dest.c);
		a.convert(dest.s);
	}
	std::string isNative(const char* typeidStr)
	{
		return std::string((std::string(typeid(MyType).name()) == typeidStr) ? "*":" ");
	}
};

//----------------------------------------
//	CreateTestDynamicAnyInstances
//----------------------------------------
template<EMyType N>
void CreateTestDynamicAnyInstances(std::vector<TestDynamicAnyBase*>& vec, TestTypes* dest)
{
	typedef typename Poco::TypeGetter<N, MyTypeList>::HeadType	MyType;

	vec[N] = new TestDynamicAny<N>(dest[N], static_cast<MyType>('A'-N));
	CreateTestDynamicAnyInstances<static_cast<EMyType>(N+1)>(vec, dest);	// recursive call
}

template<>
void CreateTestDynamicAnyInstances<eTypeBool>(std::vector<TestDynamicAnyBase*>& vec, TestTypes* dest)
{
	vec[eTypeBool] = new TestDynamicAny<eTypeBool>(dest[eTypeBool], true);
}

template<>
void CreateTestDynamicAnyInstances<eTypeString>(std::vector<TestDynamicAnyBase*>& vec, TestTypes* dest)
{
	vec[eTypeString] = new TestDynamicAny<eTypeString>(dest[eTypeString], std::string("54"));
	CreateTestDynamicAnyInstances<static_cast<EMyType>(eTypeString+1)>(vec, dest);	// recursive call
}

//----------------------------------------
//	DeleteTestDynamicAnyInstance
//----------------------------------------
class DeleteTestDynamicAnyInstance
{
public:
	void operator () (TestDynamicAnyBase* ptr)
	{
		delete ptr;
	}
};

//----------------------------------------
//	PrepareConsoleLogger
//----------------------------------------
void PrepareConsoleLogger(const std::string& name, int level=Poco::Message::PRIO_INFORMATION)
{
	Poco::FormattingChannel* pFCConsole = new Poco::FormattingChannel(new Poco::PatternFormatter("%t"));
	pFCConsole->setChannel(new Poco::ConsoleChannel);
	pFCConsole->open();

	Poco::Logger::create(name, pFCConsole, level);
}

//----------------------------------------
//	main
//----------------------------------------
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);

	ScopedLogMessage msg("DynamicAnyTest ", "start", "end");

	TestTypes dest[kNumMyTypeKind];
	std::vector<TestDynamicAnyBase*> vec(kNumMyTypeKind);

	CreateTestDynamicAnyInstances<eTypeChar>(vec, &dest[0]);

	std::string resultStr[kNumMyTypeKind];
	for(int i=0; i<kNumMyTypeKind; ++i)
	{
		resultStr[eTypeChar]	+= Poco::format("%3?i%s   ", dest[i].c,   vec[i]->isNative(typeid(char).name()));
		resultStr[eTypeInt8]	+= Poco::format("%3?i%s   ", dest[i].i8,  vec[i]->isNative(typeid(Poco::Int8).name()));
		resultStr[eTypeUInt8]	+= Poco::format("%3?i%s   ", dest[i].u8,  vec[i]->isNative(typeid(Poco::UInt8).name()));
		resultStr[eTypeInt16]	+= Poco::format("%3?i%s   ", dest[i].i16, vec[i]->isNative(typeid(Poco::Int16).name()));
		resultStr[eTypeUInt16]	+= Poco::format("%3?i%s   ", dest[i].u16, vec[i]->isNative(typeid(Poco::UInt16).name()));
		resultStr[eTypeInt32]	+= Poco::format("%3?i%s   ", dest[i].i32, vec[i]->isNative(typeid(Poco::Int32).name()));
		resultStr[eTypeUInt32]	+= Poco::format("%3?i%s   ", dest[i].u32, vec[i]->isNative(typeid(Poco::UInt32).name()));
		resultStr[eTypeInt64]	+= Poco::format("%3?i%s   ", dest[i].i64, vec[i]->isNative(typeid(Poco::Int64).name()));
		resultStr[eTypeUInt64]	+= Poco::format("%3?i%s   ", dest[i].u64, vec[i]->isNative(typeid(Poco::UInt64).name()));
		resultStr[eTypeFloat]	+= Poco::format("%6.2hf%s",  dest[i].f,   vec[i]->isNative(typeid(float).name()));
		resultStr[eTypeDouble]	+= Poco::format("%6.2f%s",   dest[i].d,   vec[i]->isNative(typeid(double).name()));
		resultStr[eTypeString]	+= Poco::format("%4s%s  ",   Poco::format("\"%s\"", dest[i].s), vec[i]->isNative(typeid(std::string).name()));
		resultStr[eTypeBool]	+= Poco::format("%3b%s   ",  dest[i].b,   vec[i]->isNative(typeid(bool).name()));
	}

	std::for_each(vec.begin(), vec.end(), DeleteTestDynamicAnyInstance());

	for(int i=0; i<kNumMyTypeKind; ++i)
	{
		msg.Message(Poco::format("%13s %s", kMyTypeName[i], resultStr[i]));
	}
	msg.Message("                "
				"(NOTE: item with trailing '*' indicates it's the source)");

	return 0;
}