1 /**
2    Any type
3  */
4 module xlld.any;
5 
6 ///
7 struct Any {
8     import xlld.sdk.xlcall: XLOPER12;
9 
10     ///
11     XLOPER12 _impl;
12     alias _impl this;
13 
14     ///
15     bool opEquals(Any other) @trusted const {
16         import xlld.sdk.xlcall: XlType;
17         import xlld.conv.from: fromXlOper;
18 
19         switch(_impl.xltype) {
20 
21         default:
22             return _impl == other._impl;
23 
24         case XlType.xltypeStr:
25 
26             import std.experimental.allocator.gc_allocator: GCAllocator;
27             return _impl.fromXlOper!string(GCAllocator.instance) ==
28                 other._impl.fromXlOper!string(GCAllocator.instance);
29 
30         case XlType.xltypeMulti:
31 
32             if(_impl.val.array.rows != other._impl.val.array.rows) return false;
33             if(_impl.val.array.columns != other._impl.val.array.columns) return false;
34 
35             int i;
36             foreach(r; 0 .. _impl.val.array.rows) {
37                 foreach(c; 0 .. _impl.val.array.columns) {
38                     if(Any(cast(XLOPER12)_impl.val.array.lparray[i]) !=
39                        Any(cast(XLOPER12)other._impl.val.array.lparray[i]))
40                         return false;
41                     ++i;
42                 }
43             }
44 
45             return true;
46         }
47     }
48 
49     ///
50     string toString() @safe const {
51         import std.conv: text;
52         import xlld.sdk.xlcall: XlType;
53         import xlld.conv.from: fromXlOper;
54         import xlld.sdk.xlcall: xlbitXLFree, xlbitDLLFree;
55         import std.experimental.allocator.gc_allocator: GCAllocator;
56 
57         alias allocator = GCAllocator.instance;
58 
59         string ret = text("Any(", );
60         const type = _impl.xltype & ~(xlbitXLFree | xlbitDLLFree);
61         switch(type) {
62         default:
63             ret ~= type.text;
64             break;
65         case XlType.xltypeStr:
66             ret ~= () @trusted { return text(`"`, _impl.fromXlOper!string(allocator), `"`); }();
67             break;
68         case XlType.xltypeNum:
69             ret ~= () @trusted { return _impl.fromXlOper!double(allocator).text; }();
70             break;
71         case XlType.xltypeInt:
72             ret ~= () @trusted { return _impl.fromXlOper!int(allocator).text; }();
73             break;
74         case XlType.xltypeMulti:
75             int i;
76             ret ~= `[`;
77             const rows = () @trusted { return _impl.val.array.rows; }();
78             const cols = () @trusted { return _impl.val.array.columns; }();
79             foreach(r; 0 .. rows) {
80                 ret ~= `[`;
81                 foreach(c; 0 .. cols) {
82                     auto oper = () @trusted { return _impl.val.array.lparray[i++]; }();
83                     ret ~= text(Any(cast(XLOPER12)oper), `, `);
84                 }
85                 ret ~= `]`;
86             }
87             ret ~= `]`;
88             break;
89         }
90         return ret ~ ")";
91     }
92 
93 }
94 
95 
96 ///
97 auto any(T, A)(auto ref T value, auto ref A allocator, in string file = __FILE__, in size_t line = __LINE__) @trusted {
98     import xlld.conv: toXlOper;
99     static if(__traits(compiles, Any(value.toXlOper(allocator, file, line))))
100         return Any(value.toXlOper(allocator, file, line));
101     else
102         return Any(value.toXlOper(allocator));
103 }