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
8namespace mojo {
9
10// Specialize the following class:
11//   template <typename T, typename U> struct TypeConverter;
12// to perform type conversion for Mojom-defined structs and arrays. Here, T is
13// the target type; U is the input type.
14//
15// Specializations should implement the following interfaces:
16//   namespace mojo {
17//   template <>
18//   struct TypeConverter<X, Y> {
19//     static X Convert(const Y& input);
20//   };
21//   template <>
22//   struct TypeConverter<Y, X> {
23//     static Y Convert(const X& input);
24//   };
25//   }
26//
27// EXAMPLE:
28//
29// Suppose you have the following Mojom-defined struct:
30//
31//   module geometry {
32//   struct Point {
33//     int32 x;
34//     int32 y;
35//   };
36//   }
37//
38// Now, imagine you wanted to write a TypeConverter specialization for
39// gfx::Point. It might look like this:
40//
41//   namespace mojo {
42//   template <>
43//   struct TypeConverter<geometry::PointPtr, gfx::Point> {
44//     static geometry::PointPtr Convert(const gfx::Point& input) {
45//       geometry::PointPtr result;
46//       result->x = input.x();
47//       result->y = input.y();
48//       return result.Pass();
49//     }
50//   };
51//   template <>
52//   struct TypeConverter<gfx::Point, geometry::PointPtr> {
53//     static gfx::Point Convert(const geometry::PointPtr& input) {
54//       return input ? gfx::Point(input->x, input->y) : gfx::Point();
55//     }
56//   };
57//   }
58//
59// With the above TypeConverter defined, it is possible to write code like this:
60//
61//   void AcceptPoint(const geometry::PointPtr& input) {
62//     // With an explicit cast using the .To<> method.
63//     gfx::Point pt = input.To<gfx::Point>();
64//
65//     // With an explicit cast using the static From() method.
66//     geometry::PointPtr output = geometry::Point::From(pt);
67//
68//     // Inferring the input type using the ConvertTo helper function.
69//     gfx::Point pt2 = ConvertTo<gfx::Point>(input);
70//   }
71//
72template <typename T, typename U>
73struct TypeConverter;
74
75// The following specialization is useful when you are converting between
76// Array<POD> and std::vector<POD>.
77template <typename T>
78struct TypeConverter<T, T> {
79  static T Convert(const T& obj) { return obj; }
80};
81
82// The following helper function is useful for shorthand. The compiler can infer
83// the input type, so you can write:
84//   OutputType out = ConvertTo<OutputType>(input);
85template <typename T, typename U>
86inline T ConvertTo(const U& obj) {
87  return TypeConverter<T, U>::Convert(obj);
88};
89
90}  // namespace mojo
91
92#endif  // MOJO_PUBLIC_CPP_BINDINGS_TYPE_CONVERTER_H_
93