OLD | NEW |
| (Empty) |
1 // Copyright 2010 The Ginsu Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can | |
3 // be found in the LICENSE file. | |
4 | |
5 #include "c_salt/converting_visitor.h" | |
6 | |
7 #include <cctype> | |
8 #include <cmath> | |
9 #include <limits> | |
10 #include <sstream> | |
11 | |
12 #include "c_salt/scripting_bridge.h" | |
13 #include "c_salt/scripting_interface.h" | |
14 | |
15 namespace c_salt { | |
16 | |
17 std::string ConvertingVisitor<std::string>::operator()(bool value) const { | |
18 return std::string(value ? "true" : "false"); | |
19 } | |
20 | |
21 std::string ConvertingVisitor<std::string>::operator()(double value) const { | |
22 std::ostringstream stream; | |
23 // Try to get enough places after the decimal so that converting back | |
24 // to a double type preserves as much of the precision as possible. | |
25 // This says to represent floating point types with a fixed number of | |
26 // digits. | |
27 stream.setf(std::ios::fixed, std::ios::floatfield); | |
28 // digits10 means "the smallest number of digits in base 10 that can | |
29 // represent double without loss of precision" | |
30 stream.precision(std::numeric_limits<double>::digits10); | |
31 stream << value; | |
32 return stream.str(); | |
33 } | |
34 | |
35 std::string ConvertingVisitor<std::string>::operator()(int32_t value) const { | |
36 std::ostringstream stream; | |
37 stream << value; | |
38 return stream.str(); | |
39 } | |
40 | |
41 // In this case, we can just pass the same const-reference out, since it | |
42 // exists in the variant. In all other cases, we have to copy because we are | |
43 // creating a std::string on the stack. | |
44 const std::string& | |
45 ConvertingVisitor<std::string>::operator()(const std::string& value) const { | |
46 return value; | |
47 } | |
48 | |
49 std::string ConvertingVisitor<std::string>::operator()( | |
50 const SharedScriptingInterface& value) const { | |
51 // TODO(dspringer, dmichael): Should we bother converting it to a string, | |
52 // a-la JSON? | |
53 return std::string(); | |
54 } | |
55 | |
56 SharedScriptingInterface | |
57 ConvertingVisitor<SharedScriptingInterface>::operator()( | |
58 const SharedScriptingInterface& value) const { | |
59 return value; | |
60 } | |
61 | |
62 SharedScriptableNativeObject | |
63 ConvertingVisitor<SharedScriptableNativeObject>::operator()( | |
64 const SharedScriptingInterface& value) const { | |
65 // We can only convert it to a native object if it is in fact implemented on | |
66 // the Native side. | |
67 if (value->IsNative()) { | |
68 SharedScriptingBridge bridge = | |
69 boost::static_pointer_cast<ScriptingBridge>(value); | |
70 SharedScriptableNativeObject sno = bridge->native_object(); | |
71 return sno; | |
72 } | |
73 // If it's not native, we can't support this conversion. Return a NULL. | |
74 return SharedScriptableNativeObject(); | |
75 } | |
76 | |
77 bool ConvertingVisitor<bool>::operator()(bool value) const { | |
78 return value; | |
79 } | |
80 | |
81 bool ConvertingVisitor<bool>::operator()(int32_t value) const { | |
82 return (value != 0); | |
83 } | |
84 | |
85 bool ConvertingVisitor<bool>::operator()(double value) const { | |
86 // Return |true| if |value| is non-0 within machine epsilon. | |
87 return (std::fabs(value) > std::numeric_limits<double>::epsilon()); | |
88 } | |
89 | |
90 bool ConvertingVisitor<bool>::operator()(const std::string& value) const { | |
91 if (value.empty()) return false; | |
92 int ch = std::tolower(value[0]); | |
93 return ch == 'y' || ch == '1' || ch == 't'; | |
94 } | |
95 | |
96 bool ConvertingVisitor<bool>::operator()( | |
97 const SharedScriptingInterface& value) const { | |
98 return static_cast<bool>(value); // Return true if value is not null. | |
99 } | |
100 | |
101 int32_t ConvertingVisitor<int32_t>::operator()(bool value) const { | |
102 return value ? 1 : 0; | |
103 } | |
104 | |
105 int32_t ConvertingVisitor<int32_t>::operator()(int32_t value) const { | |
106 return value; | |
107 } | |
108 | |
109 int32_t ConvertingVisitor<int32_t>::operator()(double value) const { | |
110 return static_cast<int32_t>(value); | |
111 } | |
112 | |
113 int32_t ConvertingVisitor<int32_t>::operator()(const std::string& value) const { | |
114 std::istringstream input_stream(value); | |
115 int32_t int_value(0); | |
116 // This may fail, in which case int_value remains 0. | |
117 input_stream >> int_value; | |
118 return int_value; | |
119 } | |
120 | |
121 int32_t ConvertingVisitor<int32_t>::operator()( | |
122 const SharedScriptingInterface& value) const { | |
123 return 0; | |
124 } | |
125 | |
126 double ConvertingVisitor<double>::operator()(bool value) const { | |
127 return value ? 1.0 : 0.0; | |
128 } | |
129 | |
130 double ConvertingVisitor<double>::operator()(int32_t value) const { | |
131 // Truncate value. E.g., 3.5 -> 3, and -3.5 -> -3. | |
132 // We don't use floor because it always converts to the largest | |
133 // integer _less_than_or_equal_ to the given double. E.g., | |
134 // -3.5 -> -4 | |
135 return static_cast<double>(value); | |
136 } | |
137 | |
138 double ConvertingVisitor<double>::operator()(double value) const { | |
139 return value; | |
140 } | |
141 | |
142 double ConvertingVisitor<double>::operator()(const std::string& value) const { | |
143 std::istringstream input_stream(value); | |
144 double double_value(0.0); | |
145 // This may fail, in which case double_value remains 0.0. | |
146 input_stream >> double_value; | |
147 return double_value; | |
148 } | |
149 | |
150 double ConvertingVisitor<double>::operator()( | |
151 const SharedScriptingInterface& value) const { | |
152 return 0.0; | |
153 } | |
154 | |
155 } // namespace c_salt | |
OLD | NEW |