1 /******************************************************************************
2 
3     CTFE functions and templates used for code generation to be used with
4     ocean.task.Task
5 
6     Copyright:
7         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
8         All rights reserved.
9 
10     License:
11         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
12         Alternatively, this file may be distributed under the terms of the Tango
13         3-Clause BSD License (see LICENSE_BSD.txt for details).
14 
15 ******************************************************************************/
16 
17 module ocean.task.internal.TaskExtensionMixins;
18 
19 
20 import ocean.meta.types.Qualifiers;
21 
22 version (unittest)
23 {
24     import ocean.core.Test;
25     import ocean.core.Tuple;
26 }
27 
28 /******************************************************************************
29 
30     For a given list of struct types generates aggregate struct type and
31     a variable/field named 'extensions' of that type.
32 
33     Refers to extensions types as `Extensions[i]` instead of actual name to
34     avoid issue with missing imports in the mixin context.
35 
36     Params:
37         Extensions = variadic template argument list of struct types
38 
39 ******************************************************************************/
40 
41 public istring genExtensionAggregate ( Extensions... ) ( )
42 {
43     istring result = "struct ExtensionAggregate\n{\n";
44 
45     foreach (i, extension; Extensions)
46     {
47         result ~= "Extensions[" ~ i.stringof ~ "] ";
48         result ~= toFieldName(extension.stringof);
49         result ~= ";\n";
50     }
51 
52     result ~= "}\nExtensionAggregate extensions;\n";
53 
54     return result;
55 }
56 
57 ///
58 unittest
59 {
60     static struct Test1 { }
61     static struct Test2 { }
62 
63     alias Tuple!(Test1, Test2) Extensions;
64     mixin (genExtensionAggregate!(Extensions)());
65 
66     /*
67         struct ExtensionAggregate
68         {
69             Extensions[0] test1;
70             Extensions[1] test2;
71         }
72 
73         ExtensionAggregate extensions;
74      */
75 
76     static assert (is(typeof(extensions.test1) == Test1));
77     static assert (is(typeof(extensions.test2) == Test2));
78 }
79 
80 /******************************************************************************
81 
82     CTFE helper for field name generation
83 
84     Params:
85         type_name = CamelCase struct/class type name
86 
87     Returns:
88         Matching field name using lower_case
89 
90 ******************************************************************************/
91 
92 private mstring toFieldName ( istring type_name )
93 {
94     mstring result;
95 
96     foreach (index, char c; type_name)
97     {
98         if (c >= 'A' && c <= 'Z')
99         {
100             if (index != 0)
101                 result ~= "_";
102             result ~= cast(char) (c + 32);
103         }
104         else
105             result ~= c;
106     }
107 
108     return result;
109 }
110 
111 ///
112 unittest
113 {
114     test!("==")(toFieldName("DoSomeMagic"), "do_some_magic");
115     test!("==")(toFieldName("Magic"), "magic");
116 }