Turi Create  4.0
has_save.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 HAS_SAVE_HPP
7 #define HAS_SAVE_HPP
8 #include <typeinfo>
9 #include <type_traits>
10 namespace turi {
11 namespace archive_detail {
12 
13  /** SFINAE method to detect if a class T
14  * implements a function void T::save(ArcType&) const
15  *
16  * If T implements the method, has_save_method<ArcType,T>::value will be
17  * true. Otherwise it will be false
18  */
19  template<typename ArcType, typename T>
20  struct has_save_method
21  {
22  template<typename U, void (U::*)(ArcType&) const> struct SFINAE {};
23  template<typename U> static char Test(SFINAE<U, &U::save>*);
24  template<typename U> static int Test(...);
25  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
26  };
27 
28  /**
29  * save_or_fail<ArcType, T>(arc, t)
30  * will call this version of the function if
31  * T implements void T::save(ArcType&) const.
32  *
33  * save_or_fail<ArcType, T>(arc, t) will therefore save the class successfully
34  * if T implements the save function correctly. Otherwise, calling
35  * save_or_fail will print an error message.
36  */
37  template <typename ArcType, typename ValueType>
38  typename std::enable_if<has_save_method<ArcType, ValueType>::value, void>::type
39  save_or_fail(ArcType& o, const ValueType &t) {
40  t.save(o);
41  }
42 
43  /**
44  * save_or_fail<ArcType, T>(arc, t)
45  * will call this version of the function if
46  *
47  * save_or_fail<ArcType, T>(arc, t) will therefore save the class successfully
48  * if T implements the save function correctly. Otherwise, calling
49  * save_or_fail will print an error message.
50  * T does not implement void T::save(ArcType&) const.
51  */
52  template <typename ArcType, typename ValueType>
53  typename std::enable_if<!has_save_method<ArcType, ValueType>::value, void>::type
54  save_or_fail(ArcType& o, const ValueType &t) {
55  ASSERT_MSG(false,"Trying to serializable type %s without valid save method.", typeid(ValueType).name());
56  }
57 
58 } // archive_detail
59 } // turicreate
60 
61 #endif