1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
7 
8 #include <stdint.h>
9 
10 #include <vector>
11 
12 namespace mojo {
13 
14 // NOTE: TypeConverter is deprecated. Please consider StructTraits /
15 // UnionTraits / EnumTraits / ArrayTraits / MapTraits / StringTraits if you
16 // would like to convert between custom types and the wire format of mojom
17 // types.
18 //
19 // Specialize the following class:
20 //   template <typename T, typename U> struct TypeConverter;
21 // to perform type conversion for Mojom-defined structs and arrays. Here, T is
22 // the target type; U is the input type.
23 //
24 // Specializations should implement the following interfaces:
25 //   namespace mojo {
26 //   template <>
27 //   struct TypeConverter<X, Y> {
28 //     static X Convert(const Y& input);
29 //   };
30 //   template <>
31 //   struct TypeConverter<Y, X> {
32 //     static Y Convert(const X& input);
33 //   };
34 //   }
35 //
36 // EXAMPLE:
37 //
38 // Suppose you have the following Mojom-defined struct:
39 //
40 //   module geometry {
41 //   struct Point {
42 //     int32_t x;
43 //     int32_t y;
44 //   };
45 //   }
46 //
47 // Now, imagine you wanted to write a TypeConverter specialization for
48 // gfx::Point. It might look like this:
49 //
50 //   namespace mojo {
51 //   template <>
52 //   struct TypeConverter<geometry::PointPtr, gfx::Point> {
53 //     static geometry::PointPtr Convert(const gfx::Point& input) {
54 //       geometry::PointPtr result;
55 //       result->x = input.x();
56 //       result->y = input.y();
57 //       return result;
58 //     }
59 //   };
60 //   template <>
61 //   struct TypeConverter<gfx::Point, geometry::PointPtr> {
62 //     static gfx::Point Convert(const geometry::PointPtr& input) {
63 //       return input ? gfx::Point(input->x, input->y) : gfx::Point();
64 //     }
65 //   };
66 //   }
67 //
68 // With the above TypeConverter defined, it is possible to write code like this:
69 //
70 //   void AcceptPoint(const geometry::PointPtr& input) {
71 //     // With an explicit cast using the .To<> method.
72 //     gfx::Point pt = input.To<gfx::Point>();
73 //
74 //     // With an explicit cast using the static From() method.
75 //     geometry::PointPtr output = geometry::Point::From(pt);
76 //
77 //     // Inferring the input type using the ConvertTo helper function.
78 //     gfx::Point pt2 = ConvertTo<gfx::Point>(input);
79 //   }
80 //
81 template <typename T, typename U>
82 struct TypeConverter;
83 
84 template <typename T, typename U>
85 inline T ConvertTo(const U& obj);
86 
87 // The following specialization is useful when you are converting between
88 // Array<POD> and std::vector<POD>.
89 template <typename T>
90 struct TypeConverter<T, T> {
91   static T Convert(const T& obj) { return obj; }
92 };
93 
94 template <typename T, typename Container>
95 struct TypeConverter<std::vector<T>, Container> {
96   static std::vector<T> Convert(const Container& container) {
97     std::vector<T> output;
98     output.reserve(container.size());
99     for (const auto& obj : container) {
100       output.push_back(ConvertTo<T>(obj));
101     }
102     return output;
103   }
104 };
105 
106 // The following helper function is useful for shorthand. The compiler can infer
107 // the input type, so you can write:
108 //   OutputType out = ConvertTo<OutputType>(input);
109 template <typename T, typename U>
110 inline T ConvertTo(const U& obj) {
111   return TypeConverter<T, U>::Convert(obj);
112 };
113 
114 }  // namespace mojo
115 
116 #endif  // MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
117