The main problem here is that I have lots of template parameters that needs to be forwarded. It quickly becomes a mess. One little change somewhere breaks 1000s of lines of code (that's an exaggeration, but still).

So, to solve this, I keep a centralized place of typedefs and macros to shorten the types and whatnot. The problem with typedefs is that I can't create them on a global level since they depend on template parameters.

For example,

typedef Graph<NegativeWeight, DirectedType, NodeT, EdgeT> Graph_t;

Not going to happen locally. So I made a struct with these typedefs and inherited from it.

But that creates problems for global functions that uses these types, so I made macros too.

Now, I want to minimize the places I have to change if I add a parameter and change a type, etc, so I want the macros and the typedefs to be the same thing. Rely on each other, so to speak, so I don't have to change both.

At first I thought I could implement the macros as the typedefs in the struct, but obviously this didn't work so well (as seen by the example above).

So right now I removed all the typedefs and go 100% with macros.

I dunno if it's a good idea or not.

Code:

#ifndef GraphTraits_201540_H
#define GraphTraits_201540_H
#define DIRECTED_TYPE template<bool, typename, typename> class
#define GRAPH_TPL template<bool NegativeWeight, DIRECTED_TYPE DirectedType, typename NodeT = void, typename EdgeT = void>
#define EDGE_TPL template<bool NegativeWeight, DIRECTED_TYPE DirectedType, typename NodeT, typename EdgeT>
#define DIRECTED_TPL template<bool NegativeWeight, typename NodeT, typename EdgeT>
#define GENERATE_MINIMUM_SPANNING_TREE_TPL template<DIRECTED_TYPE DirectedType, typename NodeT, typename EdgeT>
#define TPL_LIST NegativeWeight, DirectedType, NodeT, EdgeT
#define DIRECTED_TPL_LIST NegativeWeight, NodeT, EdgeT
#define DIRECTED_TPL_LIST_2(x) NegativeWeight, x, NodeT, EdgeT
#define NEG_TPL_LIST true, DirectedType, NodeT, EdgeT
#define PTR_LIST ptr_thread_dangerous, 32
#define DIRECTED_NODE_BASE(x) Node< DIRECTED_TPL_LIST_2(x) >
#define DIRECTED_EDGE_BASE(x) Edge< DIRECTED_TPL_LIST_2(x) >
#define DIRECTED_TYPE_BASE(x) DirectedBase< DIRECTED_TPL_LIST_2(x) >
#define DIRECTED_TYPE_BASE_T DIRECTED_TYPE_BASE(DirectedType)
#define DIRECTED_BASE_T DIRECTED_TYPE_BASE(::Directed)
#define UNDIRECTED_BASE_T DIRECTED_TYPE_BASE(::Undirected)
#define DIRECTED_TYPE_T DirectedType< DIRECTED_TPL_LIST >
#define DIRECTED_NODE_T DIRECTED_NODE_BASE(::Directed)
#define UNDIRECTED_NODE_T DIRECTED_NODE_BASE(::Undirected)
#define DIRECTED_EDGE_T DIRECTED_EDGE_BASE(::Directed)
#define UNDIRECTED_EDGE_T DIRECTED_EDGE_BASE(::Undirected)
#define NODE_T Node< TPL_LIST >
#define NODE_NEG_T Node< NEG_TPL_LIST >
#define NODE_PTR_T mad_shared_ptr< NODE_T, PTR_LIST >
#define NODE_PTR_NEG_T mad_shared_ptr< NODE_NEG_T, PTR_LIST >
#define EDGE_T Edge< TPL_LIST >
#define GRAPH_T Graph< TPL_LIST >
#define GRAPH_NEG_T Graph< NEG_TPL_LIST >
#define WEIGHT_T typename CommonGraphTraits<NegativeWeight>::weight_t
template<bool NegativeWeight> struct CommonGraphTraits { typedef int weight_t; };
template<> struct CommonGraphTraits<false> { typedef unsigned int weight_t; };
template<typename T> struct DataTrait { T m_Data; };
template<> struct DataTrait<void> { };
#endif // GraphTraits_201540_H