LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
type_constructor.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2014, Sam Schetterer, Nathan Kutz, University of Washington
3 Authors: Sam Schetterer
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 
10 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
11 
12 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 
16 */
17 #pragma once
18 #ifndef TYPE_CONSTRUCTOR_HPP
19 #define TYPE_CONSTRUCTOR_HPP
20 #include "vartype.hpp"
21 #include "defs.hpp"
22 #include "types/example_type.hpp"
23 #include <type_traits>
24 //
25 //There has to be a better way to combine this and satisfy the compiler...
26 //
27 
28 /*
29  * Function to iterate over a list of types, helps satisfy the compiler
30  */
31 
37 template<class ...P>
39  template<class Tout, template<class> class Toh, template <class, class> class Tcr, class Tf, class ...Tl>
40  static Toh<Tout>* __create(const vartype* tval){
41 
42  static_assert(std::is_floating_point<typename float_traits<Tf>::type>::value,
43  "The float_traits of the current class is not a floating point type");
44  if(tval->compare<Tf>()){
45  return new Tcr<Tf, Tout>();
46  }
47  else return __create<Tout, Toh, Tcr, Tl...>(tval);
48  }
49  template<class Tout, template<class> class Toh, template <class, class> class Tcr>
50  static Toh<Tout>* __create(const vartype* tval){
51  //has failed creation process
52  std::string val("Type ");
53  val.append(tval->vname());
54  val.append(" is not recognized as a valid input type for ");
55  val.append(typeid(Tout).name());
56  err(val, "typelist::__create", "utils/type_constructor.hpp", FATAL_ERROR);
57  return 0;//This simply satisfies static analyzers, err will always exit in this case
58  }
59  template<class Tout, template<class> class Toh, template<class, class> class Tcr>
60  static void create(Toh<Tout>** in, const vartype* val){
61  (*in)= __create<Tout, Toh, Tcr, P...>(val);
62  }
63  public:
64  typelist(){};
65  template<template<class> class U>
66  friend class type_constructor;
67 };
69 template<class ...P>
71  //The extra template parameter seems to help the compiler
72  // instantiate the recursion so it stays. It isn't part of the outer face so
73  // whatever works.
74  template<class Tout, class Tf, class ...Tl>
75  static bool __check(const vartype* tval){
76  if(tval->compare<Tf>()){
77  //has failed blacklist
78  //
79  return true;
80  }
81  else return __check<Tout, Tl...>(tval);
82  }
83  template<class Tout>
84  static bool __check(const vartype* tval){
85  //has passed
86  return false;//This simply satisfies static analyzers, err will always exit in this case
87  }
88  static bool check(const vartype* val){
89  return __check<int, P...>(val);
90  }
91  public:
92  blacklist(){};
93  template< template<class> class U>
94  friend class type_constructor;
95 };
96 
98 
160 template<template<class> class Tin>
163  template<class Tout>
164  class _ttype{
165  public:
166  virtual std::shared_ptr<Tout> create() = 0;
167  virtual ~_ttype(){}
168  };
170  template<class Tval, class Tout>
171  class ttype: public _ttype<Tout>{
172  public:
174  std::shared_ptr<Tout> create(){
175  return std::make_shared<Tin<Tval> >();
176  }
177  virtual ~ttype(){}
178  };
179 
180  public:
181 
188 
190 
204  template<class Tout,
205  class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type>
206  static void create(std::shared_ptr<Tout>* in, const vartype* tval){
207  _ttype<Tout>* temp;
208  std_type_list::create<Tout, _ttype, ttype>(&temp, tval);
209  (*in) = temp->create();
210  delete temp;
211  }
212  //This is an identical verison of above, except is accepts a blacklist against the standard typelist
213  template<class Tl,class Tout,
214  class = typename std::enable_if<std::is_base_of<vartype, Tout>::value >::type,
215  class = typename std::enable_if<std::is_base_of<blacklist_checker, Tl>::value >::type>
216  static void create(std::shared_ptr<Tout>* in, const vartype* tval){
217  _ttype<Tout>* temp;
218  if(Tl::check(tval)){
219  std::string val("Type ");
220  val.append(tval->vname());
221  val.append(" is blacklisted as an input type for ");
222  val.append(typeid(Tout).name());
223  err(val, "type_constructor::create", "utils/type_constructor.hpp", FATAL_ERROR);
224  }
225  std_type_list::create<Tout, _ttype, ttype>(&temp, tval);
226  (*in) = temp->create();
227  delete temp;
228  }
229 
231  //The list type is unspecified, so you can call this with a blacklist, a whitelist, or neither
232  template<class Tout>
233  static std::shared_ptr<Tout> create(const vartype* tval){
234  std::shared_ptr<Tout> rval;
235  type_constructor<Tin>::create<Tout>(&rval, tval);
236  return rval;
237  }
239  template<class Tl, class Tout>
240  static std::shared_ptr<Tout> create(const vartype* tval, const Tl blist){
241  std::shared_ptr<Tout> rval;
242  type_constructor<Tin>::create<Tl, Tout>(&rval, tval, blist);
243  return rval;
244  }
245 };
246 #endif