Turi Create  4.0
has_load.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_HAS_LOAD_HPP
7 #define TURI_HAS_LOAD_HPP
8 
9 #include <typeinfo>
10 #include <type_traits>
11 
12 namespace turi {
13  namespace archive_detail {
14 
15  /** SFINAE method to detect if a class T
16  * implements a function void T::load(ArcType&)
17  *
18  * If T implements the method, has_load_method<ArcType,T>::value will be
19  * true. Otherwise it will be false
20  */
21  template<typename ArcType, typename T>
22  struct has_load_method
23  {
24  template<typename U, void (U::*)(ArcType&)> struct SFINAE {};
25  template<typename U> static char Test(SFINAE<U, &U::load>*);
26  template<typename U> static int Test(...);
27  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
28  };
29 
30  /**
31  * load_or_fail<ArcType, T>(arc, t)
32  * will call this version of the function if
33  * T implements void T::load(ArcType&).
34  *
35  * load_or_fail<ArcType, T>(arc, t) will therefore load the class successfully
36  * if T implements the load function correctly. Otherwise, calling
37  * load_or_fail will print an error message.
38  */
39  template <typename ArcType, typename ValueType>
40  typename std::enable_if<has_load_method<ArcType, ValueType>::value, void>::type
41  load_or_fail(ArcType& o, ValueType &t) {
42  t.load(o);
43  }
44 
45  /**
46  * load_or_fail<ArcType, T>(arc, t)
47  * will call this version of the function if
48  *
49  * load_or_fail<ArcType, T>(arc, t) will therefore load the class successfully
50  * if T implements the load function correctly. Otherwise, calling
51  * load_or_fail will print an error message.
52  * T does not implement void T::load(ArcType&).
53  */
54  template <typename ArcType, typename ValueType>
55  typename std::enable_if<!has_load_method<ArcType, ValueType>::value, void>::type
56  load_or_fail(ArcType& o, ValueType &t) {
57  ASSERT_MSG(false, "Trying to deserializable type %s without valid load method.", typeid(ValueType).name());
58  }
59 
60  } // archive_detail
61 } // turicreate
62 
63 #endif