Difficulty: Advanced
Deadline: 7 August 2004 at 19:00 GMT
Description
In set theory, the difference operator, expressed A-B, is the set of all elements of A that are not in B. For example, if A = {1,2,3,4,5} and B = {3,4,5,6,7}, A-B = {1,2}.
The symmetric difference operator of two sets A and B, expressed as A\B, is defined as (A-B) union (B-A). It consists of all the elements in A not in B as well as the elements in B not in A. Using A = {1,2,3,4,5} and B = {3,4,5,6,7} as above, A\B = {1,2,6,7}.
You will write a template metaprogram that receives two lists of integers and performs a symmetric difference operation on them at compile time.
Prototype
- Code: Select all
template <class List1, class List2>
struct symmetric_difference : counter< symmetric_difference<List1,List2> >
{
typedef /*implementation here*/ result;
};
A list is constructed in a manner similar to lists in Lisp or Scheme, from the following types:
- Code: Select all
namespace list
{
template <int N, class Next>
struct element { };
struct end { };
}
element is a 2-tuple container that holds one integer in the list (N) and the rest of the list (Next). The list is terminated by the end structure. An example of the lists corresponding to A and B:
- Code: Select all
using namespace list;
typedef element<1,
element<2,
element<3,
element<4,
element<5, end> > > > > A;
typedef element<3,
element<4,
element<5,
element<6,
element<7, end> > > > > B;
}
Each type you create to aid your computation must inherit from counter<Type>, where Type is the typename you are creating. See the prototype for an example. The counter type will count the number of template instantiations in your metaprogram.
Two header files are provided for your use: counter.hpp and list.hpp.
Optimize for: minimum template instantiation
Each unique type generated in the computation of your answer counts as one template instantiation. The count gathers in static_counter::count.
Example
Given the types from above, your code should satisfy the following:
- Code: Select all
using namespace list;
typedef element<1,
element<2,
element<6,
element<7, end> > > > A_diff_B;
typedef symmetric_difference<A,B>::result your_answer;
assert(is_same_type<your_answer, A_diff_B>::result);
// the following should print "1 2 6 7"
print<your_answer>();
// the following outputs the total number of template instantiations
cout << static_counter::count << endl;
Notes
- You must compute the values at compile-time.
- Your solution must be source-compatible to the provided prototype.
- No number will occur more than once in any input list, but the input lists will not necessarily be sorted.
- Your answer must be sorted.
Submissions
Please attach your solution as a single header file in an email to ryan@cpp-home.com, with the subject line as "Contest 42".
Post any questions or comments in this thread. Good luck and enjoy!
