Design Question, Templates?

Not sure what the best title would be :p

Currently I have a macro. Its rather big and I'm wondering how to get rid of it. I'm not sure if I've just been awake for too long or it can't be done the way I want.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define __VARIABLE_DESC_LIST(type, access)																			\
	std::string accessed;																							\
	const type *pList = reinterpret_cast<const type *>(pDescVar->pValue);											\
	const char *listSeperator = options.m_newLineLists ? "#[c:push]#[cp],#[c:pop]\n" : "#[c:push]#[cp], #[c:pop]";	\
	std::map<std::string, bool> used;																				\
																													\
	auto iter = pList->begin();																						\
	if (iter != pList->end())																						\
	{																												\
		accessed = access;																							\
		used[accessed] = true;																						\
		buff = StrCopy(buff, accessed.c_str());																		\
																													\
		++iter;																										\
																													\
		if (options.m_noRepeatList)																					\
		{																											\
			for ( ; iter != pList->end(); ++iter)																	\
			{																										\
				accessed = access;																					\
				if (used.find(accessed) == used.end())																\
				{																									\
					buff = StrCopy(buff, listSeperator);															\
					used[accessed] = true;																			\
					buff = StrCopy(buff, accessed.c_str());															\
				}																									\
			}																										\
		}																											\
		else																										\
		{																											\
			for ( ; iter != pList->end(); ++iter)																	\
			{																										\
				buff = StrCopy(buff, listSeperator);																\
				buff = StrCopy(buff, access##.c_str());																\
			}																										\
		}																											\
	} 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
case DESC_VAR_LIST_OF_ITEMS:
{
	__VARIABLE_DESC_LIST(CItem::PtrVectorOf, (*iter)->GetName());
}
break;

case DESC_VAR_LIST_OF_ENCHANTS:
{
	__VARIABLE_DESC_LIST(CAttribute::INSTANCE::VectorOf, GAME->GetAttributeManager()->GetAttribute((*iter).attrID)->GetName());
}
break;

case DESC_VAR_LIST_OF_ITEM_INSTANCES:
{
	__VARIABLE_DESC_LIST(CItemInstance::VectorOf, (*iter).GetNameAndQuantity());
}
break;


Is there a way a template or function take a parameter that will help with the access. I'm not sure how to go about it. I want a function/template to output these lists, but they each access information differently. Or maybe i should just stick with the macro.

Am i thinking about this all wrong? Maybe I should sleep and check back on it :p
closed account (10X9216C)
Well you could just create a function that takes a string instead of a macro that does the samething.

1
2
3
4
5
6
void DoMagic( ... , const std::string& accessed)
{
}

DoMagic( ... , (*iter)->GetName());


I don't really see a reason for you to have to pass that as macro.

You could probably do templates for array/list stuff you are doing, can't get into the details right now...
I'm not sure what you mean. I'm not passing a string into a macro, I'm passing what's to be copied into the macro. That's how the list is used to get the string each time it loops. Maybe I'm thinking of what you mean wrong. I'll keep trying anyway ty.
Well I don't know if its a good way, but this works:

I put the macro mostly into a templated function. As a parameter to the function I take in a function ptr which is used to decide how the iter is used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
template <typename type> void __test(const void *pValue, std::string & output, const CVariableDescriptionOptions *pOptions, const std::function<std::string(typename const type::const_iterator & iter)> access)
{
	const type *pList = reinterpret_cast<const type *>(pValue);
		
	const char *listSeperator = pOptions->IsNewLineList() ? "#[c:push]#[cp],#[c:pop]\n" : "#[c:push]#[cp], #[c:pop]";

	auto iter = pList->begin();
	if (iter != pList->end())
	{
		std::map<std::string, bool> used;
		std::string accessed = access(iter);
		used[accessed] = true;
		output += accessed;
		++iter;

		if (pOptions->IsNoRepeatList())
		{
			for ( ; iter != pList->end(); ++iter)
			{
				accessed = access(iter);
				if (used.find(accessed) == used.end())
				{
					output += listSeperator;
					output += accessed;
					used[accessed] = true;
				}
			}
		}
		else
		{
			for ( ; iter != pList->end(); ++iter)
			{
				output += listSeperator;
				output += access(iter);
			}
		}
	}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
case DESC_VAR_LIST_OF_ITEMS:
{
	__test<CItem::PtrVectorOf>(pValue, output, pOptions, [](const std::vector<std::string>::const_iterator & iter)
	-> std::string
	{
		return (*iter)->GetName();
	});
}
break;

case DESC_VAR_LIST_OF_ENCHANTS:
{
	__test<CAttribute::INSTANCE::VectorOf>(pValue, output, pOptions, [](const CAttribute::INSTANCE::VectorOf::const_iterator & iter)
	-> std::string
	{
		return GAME->GetAttributeManager()->GetAttribute((*iter).attrID)->GetName();
	});
}
break;

case DESC_VAR_LIST_OF_ITEM_INSTANCES:
{
	__test<CItemInstance::VectorOf>(pValue, output, pOptions, [](const CItemInstance::VectorOf::const_iterator & iter)
	-> std::string
	{
		return (*iter).GetNameAndQuantity()
	});
}
break;

case DESC_VAR_LIST_OF_STDSTRING:
{
	__test<std::vector<std::string>>(pValue, output, pOptions, [](const std::vector<std::string>::const_iterator & iter)
	-> std::string
	{
		return (*iter);
	});
}
break;


etc. Gotta still double check everything. But i think this is what I wanted. Anyway ty.
Topic archived. No new replies allowed.