]> git.mxchange.org Git - simgear.git/commitdiff
Add from_nasal helper and fix to_nasal for std::vector.
authorThomas Geymayer <tomgey@gmail.com>
Sat, 10 Nov 2012 13:18:27 +0000 (14:18 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sat, 10 Nov 2012 13:34:18 +0000 (14:34 +0100)
simgear/nasal/cppbind/CMakeLists.txt
simgear/nasal/cppbind/cppbind_test.cxx
simgear/nasal/cppbind/from_nasal.cxx [new file with mode: 0644]
simgear/nasal/cppbind/from_nasal.hxx [new file with mode: 0644]
simgear/nasal/cppbind/from_nasal_detail.hxx [new file with mode: 0644]
simgear/nasal/cppbind/to_nasal.hxx

index d77731a98266265b02da629ebd3dcebe5744451e..fecfb8ea47173f7240c5786823cadc3e5fc708bd 100644 (file)
@@ -2,11 +2,14 @@ include (SimGearComponent)
 
 set(HEADERS
   NasalHash.hxx
+  from_nasal_detail.hxx
+  from_nasal.hxx
   to_nasal.hxx
 )
 
 set(SOURCES
   NasalHash.cxx
+  from_nasal.cxx
   to_nasal.cxx
 )
 
index 48269a8e8c29a00b337dda59ab353296cb829787..6bf768a4c43f90316a8fd683c07b244361471c6e 100644 (file)
@@ -1,4 +1,6 @@
 #include "NasalHash.hxx"
+#include "from_nasal.hxx"
+#include "to_nasal.hxx"
 
 #include <cstring>
 #include <iostream>
@@ -19,19 +21,34 @@ int main(int argc, char* argv[])
 
   r = to_nasal(c, "Test");
   VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
+  VERIFY( from_nasal<std::string>(c, r) == "Test" );
 
   r = to_nasal(c, std::string("Test"));
   VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
+  VERIFY( from_nasal<std::string>(c, r) == "Test" );
 
   r = to_nasal(c, 42);
   VERIFY( naNumValue(r).num == 42 );
+  VERIFY( from_nasal<int>(c, r) == 42 );
 
-  r = to_nasal(c, 4.2);
-  VERIFY( naNumValue(r).num == 4.2 );
+  r = to_nasal(c, 4.2f);
+  VERIFY( naNumValue(r).num == 4.2f );
+  VERIFY( from_nasal<float>(c, r) == 4.2f );
 
   std::vector<int> vec;
   r = to_nasal(c, vec);
 
+  r = to_nasal(c, "string");
+  try
+  {
+    from_nasal<int>(c, r);
+
+    std::cerr << "failed: Expected bad_nasal_cast to be thrown" << std::endl;
+    return 1;
+  }
+  catch(nasal::bad_nasal_cast&)
+  {}
+
   Hash hash(c);
   hash.set("vec", r);
   hash.set("vec2", vec);
diff --git a/simgear/nasal/cppbind/from_nasal.cxx b/simgear/nasal/cppbind/from_nasal.cxx
new file mode 100644 (file)
index 0000000..03c4dc2
--- /dev/null
@@ -0,0 +1,65 @@
+// Conversion functions to convert Nasal types to C++ types
+//
+// Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+#include "from_nasal_detail.hxx"
+#include "NasalHash.hxx"
+
+namespace nasal
+{
+  //----------------------------------------------------------------------------
+  bad_nasal_cast::bad_nasal_cast()
+  {
+
+  }
+
+  //----------------------------------------------------------------------------
+  bad_nasal_cast::bad_nasal_cast(const std::string& msg):
+   _msg( msg )
+  {
+
+  }
+
+  //----------------------------------------------------------------------------
+  bad_nasal_cast::~bad_nasal_cast() throw()
+  {
+
+  }
+
+  //----------------------------------------------------------------------------
+  const char* bad_nasal_cast::what() const throw()
+  {
+    return _msg.empty() ? bad_cast::what() : _msg.c_str();
+  }
+
+  //----------------------------------------------------------------------------
+  std::string from_nasal(naContext c, naRef ref, std::string*)
+  {
+    naRef na_str = naStringValue(c, ref);
+    return std::string(naStr_data(na_str), naStr_len(na_str));
+  }
+
+  //----------------------------------------------------------------------------
+  Hash from_nasal(naContext c, naRef ref, Hash*)
+  {
+    if( !naIsHash(ref) )
+      throw bad_nasal_cast("Not a hash");
+
+    return Hash(ref, c);
+  }
+
+} // namespace nasal
diff --git a/simgear/nasal/cppbind/from_nasal.hxx b/simgear/nasal/cppbind/from_nasal.hxx
new file mode 100644 (file)
index 0000000..e9991cb
--- /dev/null
@@ -0,0 +1,43 @@
+// Conversion functions to convert Nasal types to C++ types
+//
+// Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+#ifndef SG_FROM_NASAL_HXX_
+#define SG_FROM_NASAL_HXX_
+
+#include "from_nasal_detail.hxx"
+
+namespace nasal
+{
+
+  /**
+   * Convert a Nasal type to any supported C++ type.
+   *
+   * @note  Every type which should be supported needs a function with the
+   *        following signature declared:
+   *
+   *        Type from_nasal(naContext, naRef, Type*)
+   */
+  template<class T>
+  T from_nasal(naContext c, naRef ref)
+  {
+    return from_nasal(c, ref, static_cast<T*>(0));
+  }
+
+} // namespace nasal
+
+#endif /* SG_FROM_NASAL_HXX_ */
diff --git a/simgear/nasal/cppbind/from_nasal_detail.hxx b/simgear/nasal/cppbind/from_nasal_detail.hxx
new file mode 100644 (file)
index 0000000..d5db8cb
--- /dev/null
@@ -0,0 +1,101 @@
+// Conversion helpers used by from_nasal<T>(naContext, naRef)
+//
+// Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+#ifndef SG_FROM_NASAL_DETAIL_HXX_
+#define SG_FROM_NASAL_DETAIL_HXX_
+
+#include <simgear/nasal/nasal.h>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <string>
+#include <typeinfo> // std::bad_cast
+#include <vector>
+
+namespace nasal
+{
+  class Hash;
+
+  /**
+   * Thrown when converting a type from/to Nasal has failed
+   */
+  class bad_nasal_cast:
+    public std::bad_cast
+  {
+    public:
+      bad_nasal_cast();
+      explicit bad_nasal_cast(const std::string& msg);
+
+      virtual ~bad_nasal_cast() throw();
+      virtual const char* what() const throw();
+
+    protected:
+      std::string _msg;
+  };
+
+  /**
+   * Convert Nasal string to std::string
+   */
+  std::string from_nasal(naContext c, naRef ref, std::string*);
+
+  /**
+   * Convert a Nasal hash to a nasal::Hash
+   */
+  Hash from_nasal(naContext c, naRef ref, Hash*);
+
+  /**
+   * Convert a Nasal number to a C++ numeric type
+   */
+  template<class T>
+  typename boost::enable_if< boost::is_arithmetic<T>,
+                             T
+                           >::type
+  from_nasal(naContext c, naRef ref, T*)
+  {
+    naRef num = naNumValue(ref);
+    if( !naIsNum(num) )
+      throw bad_nasal_cast("Not a number");
+
+    return static_cast<T>(num.num);
+  }
+
+  /**
+   * Convert a Nasal vector to a std::vector
+   */
+  template<class Vector, class T>
+  typename boost::enable_if< boost::is_same<Vector, std::vector<T> >,
+                             Vector
+                           >::type
+  from_nasal(naContext c, naRef ref, Vector*)
+  {
+    if( !naIsVector(ref) )
+      throw bad_nasal_cast("Not a vector");
+
+    int size = naVec_size(ref);
+    Vector vec(size);
+
+    for(int i = 0; i < size; ++i)
+      vec[i] = from_nasal<T>(c, naVec_get(ref, i));
+
+    return vec;
+  }
+
+} // namespace nasal
+
+#endif /* SG_FROM_NASAL_DETAIL_HXX_ */
index 1166a4f495f4d9ed8401566c51b5629e4f1e2124..0fd230a0d7ca74f6796ba848509e288806607601 100644 (file)
@@ -22,7 +22,7 @@
 #include <simgear/nasal/nasal.h>
 
 #include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits.hpp>
 
 #include <string>
 #include <vector>
@@ -64,8 +64,16 @@ namespace nasal
   /**
    * Convert std::vector to Nasal vector
    */
-  template<class T>
-  naRef to_nasal(naContext c, const std::vector<T>& vec)
+  template< template<class T, class Alloc> class Vector,
+            class T,
+            class Alloc
+          >
+  typename boost::enable_if< boost::is_same< Vector<T,Alloc>,
+                                             std::vector<T,Alloc>
+                                           >,
+                             naRef
+                           >::type
+  to_nasal(naContext c, const Vector<T, Alloc>& vec)
   {
     naRef ret = naNewVector(c);
     naVec_setsize(c, ret, vec.size());