Home | History | Annotate | Download | only in bindings
      1 // Copyright 2017 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_CLONE_TRAITS_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_CLONE_TRAITS_H_
      7 
      8 #include <type_traits>
      9 #include <unordered_map>
     10 #include <vector>
     11 
     12 #include "base/optional.h"
     13 #include "mojo/public/cpp/bindings/lib/template_util.h"
     14 
     15 namespace mojo {
     16 
     17 template <typename T>
     18 struct HasCloneMethod {
     19   template <typename U>
     20   static char Test(decltype(&U::Clone));
     21   template <typename U>
     22   static int Test(...);
     23   static const bool value = sizeof(Test<T>(0)) == sizeof(char);
     24 
     25  private:
     26   internal::EnsureTypeIsComplete<T> check_t_;
     27 };
     28 
     29 template <typename T, bool has_clone_method = HasCloneMethod<T>::value>
     30 struct CloneTraits;
     31 
     32 template <typename T>
     33 T Clone(const T& input);
     34 
     35 template <typename T>
     36 struct CloneTraits<T, true> {
     37   static T Clone(const T& input) { return input.Clone(); }
     38 };
     39 
     40 template <typename T>
     41 struct CloneTraits<T, false> {
     42   static T Clone(const T& input) { return input; }
     43 };
     44 
     45 template <typename T>
     46 struct CloneTraits<base::Optional<T>, false> {
     47   static base::Optional<T> Clone(const base::Optional<T>& input) {
     48     if (!input)
     49       return base::nullopt;
     50 
     51     return base::Optional<T>(mojo::Clone(*input));
     52   }
     53 };
     54 
     55 template <typename T>
     56 struct CloneTraits<std::vector<T>, false> {
     57   static std::vector<T> Clone(const std::vector<T>& input) {
     58     std::vector<T> result;
     59     result.reserve(input.size());
     60     for (const auto& element : input)
     61       result.push_back(mojo::Clone(element));
     62 
     63     return result;
     64   }
     65 };
     66 
     67 template <typename K, typename V>
     68 struct CloneTraits<std::unordered_map<K, V>, false> {
     69   static std::unordered_map<K, V> Clone(const std::unordered_map<K, V>& input) {
     70     std::unordered_map<K, V> result;
     71     for (const auto& element : input) {
     72       result.insert(std::make_pair(mojo::Clone(element.first),
     73                                    mojo::Clone(element.second)));
     74     }
     75     return result;
     76   }
     77 };
     78 
     79 template <typename T>
     80 T Clone(const T& input) {
     81   return CloneTraits<T>::Clone(input);
     82 };
     83 
     84 }  // namespace mojo
     85 
     86 #endif  // MOJO_PUBLIC_CPP_BINDINGS_CLONE_TRAITS_H_
     87