]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/d/src/thrift/internal/ctfe.d
974db01e3a745adb7d7dd181d515827f897f7618
[ceph.git] / ceph / src / jaegertracing / thrift / lib / d / src / thrift / internal / ctfe.d
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 module thrift.internal.ctfe;
21
22 import std.conv : to;
23 import std.traits;
24
25 /*
26 * Simple eager join() for strings, std.algorithm.join isn't CTFEable yet.
27 */
28 string ctfeJoin(string[] strings, string separator = ", ") {
29 string result;
30 if (strings.length > 0) {
31 result ~= strings[0];
32 foreach (s; strings[1..$]) {
33 result ~= separator ~ s;
34 }
35 }
36 return result;
37 }
38
39 /*
40 * A very primitive to!string() implementation for floating point numbers that
41 * is evaluatable at compile time.
42 *
43 * There is a wealth of problems associated with the algorithm used (e.g. 5.0
44 * prints as 4.999…, incorrect rounding, etc.), but a better alternative should
45 * be included with the D standard library instead of implementing it here.
46 */
47 string ctfeToString(T)(T val) if (isFloatingPoint!T) {
48 if (val is T.nan) return "nan";
49 if (val is T.infinity) return "inf";
50 if (val is -T.infinity) return "-inf";
51 if (val is 0.0) return "0";
52 if (val is -0.0) return "-0";
53
54 auto b = val;
55
56 string result;
57 if (b < 0) {
58 result ~= '-';
59 b *= -1;
60 }
61
62 short magnitude;
63 while (b >= 10) {
64 ++magnitude;
65 b /= 10;
66 }
67 while (b < 1) {
68 --magnitude;
69 b *= 10;
70 }
71
72 foreach (i; 0 .. T.dig) {
73 if (i == 1) result ~= '.';
74
75 auto first = cast(ubyte)b;
76 result ~= to!string(first);
77
78 b -= first;
79 import std.math;
80 if (b < pow(10.0, i - T.dig)) break;
81 b *= 10;
82 }
83
84 if (magnitude != 0) result ~= "e" ~ to!string(magnitude);
85 return result;
86 }
87
88 unittest {
89 import std.algorithm;
90 static assert(ctfeToString(double.infinity) == "inf");
91 static assert(ctfeToString(-double.infinity) == "-inf");
92 static assert(ctfeToString(double.nan) == "nan");
93 static assert(ctfeToString(0.0) == "0");
94 static assert(ctfeToString(-0.0) == "-0");
95 static assert(ctfeToString(2.5) == "2.5");
96 static assert(ctfeToString(3.1415).startsWith("3.141"));
97 static assert(ctfeToString(2e-200) == "2e-200");
98 }