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 #ifndef C_SALT_CONVERTING_VISITOR_H_ | |
6 #define C_SALT_CONVERTING_VISITOR_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "boost/shared_ptr.hpp" | |
11 #include "boost/variant/static_visitor.hpp" | |
12 #include "c_salt/scriptable_native_object_ptrs.h" | |
13 #include "c_salt/scriptable_native_object.h" | |
14 #include "c_salt/scripting_interface_ptrs.h" | |
15 | |
16 namespace c_salt { | |
17 | |
18 class ScriptingInterface; | |
19 | |
20 // The following set of ConvertingVisitor template specializations implement the | |
21 // Visitor concept, as described here: | |
22 // http://live.boost.org/doc/libs/1_41_0/doc/html/variant/reference.html | |
23 // #variant.concepts.static-visitor | |
24 // Each instantiation of ConvertingVisitor can be passed as a static visitor to | |
25 // the boost::apply_visitor function. ConvertingVisitor<TargetType> converts | |
26 // the value held by the boost variant in to type TargetType. | |
27 // | |
28 // This one is the default, which has no implementation. We only have | |
29 // specializations implement ConvertingVisitor, as we want to have very | |
30 // fine-grained control of what each conversion does depending on the type. | |
31 template <class TargetType> | |
32 class ConvertingVisitor; | |
33 | |
34 template <> | |
35 class ConvertingVisitor<std::string> | |
36 : public boost::static_visitor<std::string> { | |
37 public: | |
38 std::string operator()(bool value) const; | |
39 std::string operator()(int32_t value) const; | |
40 std::string operator()(double value) const; | |
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& operator()(const std::string& value) const; | |
45 std::string operator()(const SharedScriptingInterface& value) const; | |
46 }; | |
47 | |
48 template <> | |
49 class ConvertingVisitor<SharedScriptingInterface > | |
50 : public boost::static_visitor<SharedScriptingInterface > { | |
51 public: | |
52 template <class T> | |
53 SharedScriptingInterface operator()(T value) const { | |
54 // This is a catch all for types other than shared_ptr to | |
55 // ScriptingInterface, none of which can be converted to | |
56 // shared_ptr<ScriptingInterface>, so we just return a default-initialized | |
57 // shared_ptr. | |
58 return SharedScriptingInterface(); | |
59 } | |
60 SharedScriptingInterface operator()( | |
61 const SharedScriptingInterface& value) const; | |
62 }; | |
63 | |
64 // This specialization handles getting a ScriptableNativeObject. Currently, we | |
65 // do NOT support converting to boost::shared_ptr<T> where T is a class which | |
66 // inherits from ScriptableNativeObject. To support it safely, we would require | |
67 // a dynamic_cast to verify the type is correct, which would violate the Google | |
68 // style guide by requiring RTTI. To support it unsafely, we could static_cast, | |
69 // but that would make strange failures happen if the user got it even slightly | |
70 // wrong. This forces them to get a SharedScriptableNativeObject and then do | |
71 // the cast themselves, which at least puts any failures at the right place | |
72 // (user code). | |
73 template <> | |
74 class ConvertingVisitor<SharedScriptableNativeObject> | |
75 : public boost::static_visitor<SharedScriptableNativeObject> { | |
76 public: | |
77 template <class T> | |
78 SharedScriptableNativeObject operator()(T value) const { | |
79 // This is a catch all for types other than shared_ptr to | |
80 // ScriptingInterface, none of which can be converted to | |
81 // shared_ptr<ScriptingInterface>, so we just return a default-initialized | |
82 // shared_ptr. | |
83 return SharedScriptableNativeObject(); | |
84 } | |
85 SharedScriptableNativeObject operator()( | |
86 const SharedScriptingInterface& value) const; | |
87 }; | |
88 | |
89 template <> | |
90 class ConvertingVisitor<bool> : public boost::static_visitor<bool> { | |
91 public: | |
92 bool operator()(bool value) const; | |
93 bool operator()(int32_t value) const; | |
94 bool operator()(double value) const; | |
95 bool operator()(const std::string& value) const; | |
96 bool operator()(const SharedScriptingInterface& value) const; | |
97 }; | |
98 | |
99 template <> | |
100 class ConvertingVisitor<int32_t> : public boost::static_visitor<int32_t> { | |
101 public: | |
102 int32_t operator()(bool value) const; | |
103 int32_t operator()(int32_t value) const; | |
104 int32_t operator()(double value) const; | |
105 int32_t operator()(const std::string& value) const; | |
106 int32_t operator()(const SharedScriptingInterface& value) const; | |
107 }; | |
108 | |
109 template <> | |
110 class ConvertingVisitor<double> : public boost::static_visitor<double> { | |
111 public: | |
112 double operator()(bool value) const; | |
113 double operator()(int32_t value) const; | |
114 double operator()(double value) const; | |
115 double operator()(const std::string& value) const; | |
116 double operator()(const SharedScriptingInterface& value) const; | |
117 }; | |
118 | |
119 } // namespace c_salt | |
120 | |
121 #endif // C_SALT_CONVERTING_VISITOR_H_ | |
OLD | NEW |