variant.h 2.2 KB
Newer Older
朔-望's avatar
朔-望 已提交
1 2
#include <iostream>

L
liuruilong 已提交
3 4
#include "common/log.h"

朔-望's avatar
朔-望 已提交
5 6 7
#pragma once

namespace paddle_mobile {
朔-望's avatar
朔-望 已提交
8 9 10 11
template <int ID, typename Type>
struct IDToType {
  typedef Type type_t;
};
朔-望's avatar
朔-望 已提交
12

朔-望's avatar
朔-望 已提交
13 14
template <typename F, typename... Ts>
struct VariantHelper {
15 16 17
  static const size_t size = sizeof(F) > VariantHelper<Ts...>::size
                                 ? sizeof(F)
                                 : VariantHelper<Ts...>::size;
朔-望's avatar
朔-望 已提交
18

19 20 21 22 23
  inline static void Destroy(size_t id, void *data) {
    if (id == typeid(F).hash_code()) {
      reinterpret_cast<F *>(data)->~F();
    } else {
      VariantHelper<Ts...>::Destroy(id, data);
朔-望's avatar
朔-望 已提交
24
    }
25
  }
朔-望's avatar
朔-望 已提交
26
};
朔-望's avatar
朔-望 已提交
27

朔-望's avatar
朔-望 已提交
28 29
template <typename F>
struct VariantHelper<F> {
30 31 32 33 34 35
  static const size_t size = sizeof(F);
  inline static void Destroy(size_t id, void *data) {
    if (id == typeid(F).hash_code()) {
      //              reinterpret_cast<F*>(data)->~F();
    } else {
      //              std::cout << "未匹配到 " << std::endl;
朔-望's avatar
朔-望 已提交
36
    }
37
  }
朔-望's avatar
朔-望 已提交
38
};
朔-望's avatar
朔-望 已提交
39

朔-望's avatar
朔-望 已提交
40 41 42
template <size_t size>
class RawData {
 public:
43 44 45 46 47 48
  char data[size];
  RawData() {}
  RawData(const RawData &raw_data) { strcpy(data, raw_data.data); }
  //      void operator=(const RawData &raw_data){
  //        strcpy(data, raw_data.data);
  //      }
朔-望's avatar
朔-望 已提交
49
};
朔-望's avatar
朔-望 已提交
50

朔-望's avatar
朔-望 已提交
51 52
template <typename... Ts>
struct Variant {
53 54 55 56 57
  Variant(const Variant &variant) {
    //        std::cout << " 赋值构造函数 " << std::endl;
    type_id = variant.type_id;
    data = variant.data;
  }
朔-望's avatar
朔-望 已提交
58

59 60 61 62
  Variant() : type_id(invalid_type()) {}
  ~Variant() {
    //        helper::Destroy(type_id, &data);
  }
朔-望's avatar
朔-望 已提交
63

朔-望's avatar
朔-望 已提交
64 65
  template <typename T, typename... Args>
  void Set(Args &&... args) {
66 67 68 69
    helper::Destroy(type_id, &data);
    new (&data) T(std::forward<Args>(args)...);
    type_id = typeid(T).hash_code();
  }
朔-望's avatar
朔-望 已提交
70

朔-望's avatar
朔-望 已提交
71 72
  template <typename T>
  T &Get() const {
73 74 75 76 77
    if (type_id == typeid(T).hash_code()) {
      return *const_cast<T *>(reinterpret_cast<const T *>(&data));
    } else {
      //      std::cout << " bad cast in variant " << std::endl;
      throw std::bad_cast();
朔-望's avatar
朔-望 已提交
78
    }
79
  }
朔-望's avatar
朔-望 已提交
80

81
  size_t TypeId() const { return type_id; }
朔-望's avatar
朔-望 已提交
82

朔-望's avatar
朔-望 已提交
83
 private:
84 85 86 87
  static inline size_t invalid_type() { return typeid(void).hash_code(); }
  typedef VariantHelper<Ts...> helper;
  size_t type_id;
  RawData<helper::size> data;
朔-望's avatar
朔-望 已提交
88
};
朔-望's avatar
朔-望 已提交
89

朔-望's avatar
朔-望 已提交
90 91 92 93
template <typename T>
struct Vistor {
  typedef T type_t;
};
朔-望's avatar
朔-望 已提交
94

朔-望's avatar
朔-望 已提交
95
}  // namespace paddle_mobile