Listing 3: Include file that specified constructor-based interface

 1 // One arg: Handle<Data> dh(arg1);
 2 
 3 template<class Arg1>
 4 explicit Handle(const Arg1& arg1)
 5 : _counted(new Counted(arg1)) { _counted->use(); }
 6 
 7 template<class Arg1>
 8 explicit Handle(Arg1& arg1)
 9 : _counted(new Counted(arg1)) { _counted->use(); }
10 
11 // Two args: Handle<Data> dh(arg1, arg2);
12 
13 #define TEMPLATE template<class Arg1, class Arg2>
14 #define CONSTRUCTOR(Arg1, Arg2) \
15    explicit Handle(Arg1& arg1, Arg2& arg2) \
16    : _counted(new Counted(arg1, arg2)) { _counted->use(); }
17 
18 TEMPLATE CONSTRUCTOR(      Arg1,       Arg2)
19 TEMPLATE CONSTRUCTOR(      Arg1, const Arg2)
20 TEMPLATE CONSTRUCTOR(const Arg1,       Arg2)
21 TEMPLATE CONSTRUCTOR(const Arg1, const Arg2)
22 
23 #undef TEMPLATE
24 #undef CONSTRUCTOR
25 
26 // Three args require  8 constructors.
27 
28 #define TEMPLATE template<class Arg1, class Arg2, class Arg3>
29 #define CONSTRUCTOR(Arg1, Arg2, Arg3) \
30    explicit Handle(Arg1& arg1, Arg2& arg2, Arg3& arg3) \
31    : _counted(new Counted(arg1, arg2, arg3)) 
        { _counted->use(); }
32 
33 TEMPLATE CONSTRUCTOR(const Arg1, const Arg2, const Arg3)
34 TEMPLATE CONSTRUCTOR(const Arg1, const Arg2,       Arg3)
35 TEMPLATE CONSTRUCTOR(const Arg1,       Arg2, const Arg3)
36 TEMPLATE CONSTRUCTOR(const Arg1,       Arg2,       Arg3)
37 TEMPLATE CONSTRUCTOR(      Arg1, const Arg2, const Arg3)
38 TEMPLATE CONSTRUCTOR(      Arg1, const Arg2,       Arg3)
39 TEMPLATE CONSTRUCTOR(      Arg1,       Arg2, const Arg3)
40 TEMPLATE CONSTRUCTOR(      Arg1,       Arg2,       Arg3)
41 
42 #undef TEMPLATE
43 #undef CONSTRUCTOR
44 
45 // Four  args require 16 constructors.
46 // Five  args require 32 constructors.
47 // Implement when needed.