]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/cppbind/from_nasal_detail.hxx
Nasal cppbindings: automatic conversion of vec2 to/from Nasal
[simgear.git] / simgear / nasal / cppbind / from_nasal_detail.hxx
1 ///@file
2 /// Conversion helpers used by from_nasal<T>(naContext, naRef)
3 ///
4 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public
8 // License as published by the Free Software Foundation; either
9 // version 2 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
19
20 #ifndef SG_FROM_NASAL_DETAIL_HXX_
21 #define SG_FROM_NASAL_DETAIL_HXX_
22
23 #include "nasal_traits.hxx"
24
25 #include <simgear/nasal/nasal.h>
26
27 #include <boost/utility/enable_if.hpp>
28 #include <boost/type_traits.hpp>
29
30 #include <string>
31 #include <typeinfo> // std::bad_cast
32 #include <vector>
33
34 namespace nasal
35 {
36   class Hash;
37
38   /**
39    * Thrown when converting a type from/to Nasal has failed
40    */
41   class bad_nasal_cast:
42     public std::bad_cast
43   {
44     public:
45       /**
46        * Construct with generic error message
47        */
48       bad_nasal_cast();
49
50       /**
51        * Construct from an error message
52        *
53        * @param msg Error message/description
54        */
55       explicit bad_nasal_cast(const std::string& msg);
56
57       virtual ~bad_nasal_cast() throw();
58
59       /**
60        * Get a description of the cause of the failed cast.
61        */
62       virtual const char* what() const throw();
63
64     protected:
65       std::string _msg;
66   };
67
68   /**
69    * Simple pass through for unified handling also of naRef.
70    */
71   inline naRef from_nasal_helper(naContext, naRef ref, naRef*) { return ref; }
72
73   /**
74    * Convert Nasal string to std::string
75    */
76   std::string from_nasal_helper(naContext c, naRef ref, std::string*);
77
78   /**
79    * Convert a Nasal hash to a nasal::Hash
80    */
81   Hash from_nasal_helper(naContext c, naRef ref, Hash*);
82
83   /**
84    * Convert a Nasal number to a C++ numeric type
85    */
86   template<class T>
87   typename boost::enable_if< boost::is_arithmetic<T>,
88                              T
89                            >::type
90   from_nasal_helper(naContext c, naRef ref, T*)
91   {
92     naRef num = naNumValue(ref);
93     if( !naIsNum(num) )
94       throw bad_nasal_cast("Not a number");
95
96     return static_cast<T>(num.num);
97   }
98
99   /**
100    * Convert a Nasal vector to a std::vector
101    */
102   template<class T>
103   std::vector<T> from_nasal_helper(naContext c, naRef ref, std::vector<T>*)
104   {
105     if( !naIsVector(ref) )
106       throw bad_nasal_cast("Not a vector");
107
108     int size = naVec_size(ref);
109     std::vector<T> vec(size);
110
111     for(int i = 0; i < size; ++i)
112       vec[i] = from_nasal_helper(c, naVec_get(ref, i), static_cast<T*>(0));
113
114     return vec;
115   }
116
117   /**
118    * Convert a Nasal vector of 2 elements to a 2d vector
119    */
120   template<class Vec2>
121   typename boost::enable_if<is_vec2<Vec2>, Vec2>::type
122   from_nasal_helper(naContext c, naRef ref, Vec2*)
123   {
124     std::vector<double> vec =
125       from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0));
126     if( vec.size() != 2 )
127       throw bad_nasal_cast("Expected vector with two elements");
128     return Vec2(vec[0], vec[1]);
129   }
130
131 } // namespace nasal
132
133 #endif /* SG_FROM_NASAL_DETAIL_HXX_ */