]> git.mxchange.org Git - simgear.git/commitdiff
cppbind: refactor to_nasal for better name lookup.
authorThomas Geymayer <tomgey@gmail.com>
Sun, 3 Mar 2013 22:39:26 +0000 (23:39 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 3 Mar 2013 22:42:40 +0000 (23:42 +0100)
Using template parameter dependent name lookup it is
now possible to create to_nasal_helper overloads
for custom types and having them used for automatic
type conversion with binding methods/member on
nasal::Ghost objects.

13 files changed:
simgear/nasal/cppbind/CMakeLists.txt
simgear/nasal/cppbind/cppbind_test.cxx
simgear/nasal/cppbind/detail/from_nasal_helper.cxx [new file with mode: 0644]
simgear/nasal/cppbind/detail/from_nasal_helper.hxx [new file with mode: 0644]
simgear/nasal/cppbind/detail/nasal_traits.hxx [new file with mode: 0644]
simgear/nasal/cppbind/detail/to_nasal_helper.cxx [new file with mode: 0644]
simgear/nasal/cppbind/detail/to_nasal_helper.hxx [new file with mode: 0644]
simgear/nasal/cppbind/from_nasal.cxx [deleted file]
simgear/nasal/cppbind/from_nasal.hxx
simgear/nasal/cppbind/from_nasal_detail.hxx [deleted file]
simgear/nasal/cppbind/nasal_traits.hxx [deleted file]
simgear/nasal/cppbind/to_nasal.cxx [deleted file]
simgear/nasal/cppbind/to_nasal.hxx

index ed8272fd5c044a0041b82dd6928f006d2022694f..0439e6ed6e6784cbfee66819aa6147f196710c81 100644 (file)
@@ -4,21 +4,22 @@ set(HEADERS
   Ghost.hxx
   NasalHash.hxx
   NasalString.hxx
-  from_nasal_detail.hxx
   from_nasal.hxx
-  nasal_traits.hxx
   to_nasal.hxx
 )
 
 set(DETAIL_HEADERS
+  detail/from_nasal_helper.hxx
   detail/functor_templates.hxx
+  detail/nasal_traits.hxx
+  detail/to_nasal_helper.hxx
 )
 
 set(SOURCES
   NasalHash.cxx
   NasalString.cxx
-  from_nasal.cxx
-  to_nasal.cxx
+  detail/from_nasal_helper.cxx
+  detail/to_nasal_helper.cxx
 )
 
 simgear_component(nasal/cppbind nasal/cppbind "${SOURCES}" "${HEADERS}")
index 90bbf8555a4995b2efed178c199f58fa53ee95e5..9508ca5d7257e64973a3351b9c42aa953203b3dc 100644 (file)
@@ -50,18 +50,21 @@ struct DoubleDerived:
 {
 
 };
+
+typedef boost::shared_ptr<Base> BasePtr;
+
 struct DoubleDerived2:
   public Derived
 {
-
+  const BasePtr& getBase() const{return _base;}
+  BasePtr _base;
 };
 
-typedef boost::shared_ptr<Base> BasePtr;
 typedef boost::shared_ptr<Derived> DerivedPtr;
 typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
 typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
 
-naRef to_nasal(naContext c, const BasePtr& base)
+naRef to_nasal_helper(naContext c, const BasePtr& base)
 {
   return nasal::Ghost<BasePtr>::create(c, base);
 }
@@ -159,7 +162,8 @@ int main(int argc, char* argv[])
   Ghost<DoubleDerivedPtr>::init("DoubleDerivedPtr")
     .bases<DerivedPtr>();
   Ghost<DoubleDerived2Ptr>::init("DoubleDerived2Ptr")
-    .bases< Ghost<DerivedPtr> >();
+    .bases< Ghost<DerivedPtr> >()
+    .member("base", &DoubleDerived2::getBase);
 
   BasePtr d( new Derived );
   naRef derived = Ghost<BasePtr>::create(c, d);
diff --git a/simgear/nasal/cppbind/detail/from_nasal_helper.cxx b/simgear/nasal/cppbind/detail/from_nasal_helper.cxx
new file mode 100644 (file)
index 0000000..a094e4f
--- /dev/null
@@ -0,0 +1,84 @@
+// 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_helper.hxx"
+#include <simgear/nasal/cppbind/NasalHash.hxx>
+#include <simgear/nasal/cppbind/NasalString.hxx>
+
+#include <simgear/misc/sg_path.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_helper(naContext c, naRef ref, const std::string*)
+  {
+    naRef na_str = naStringValue(c, ref);
+    return std::string(naStr_data(na_str), naStr_len(na_str));
+  }
+
+  //----------------------------------------------------------------------------
+  SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*)
+  {
+      naRef na_str = naStringValue(c, ref);
+      return SGPath(std::string(naStr_data(na_str), naStr_len(na_str)));
+  }
+
+  //----------------------------------------------------------------------------
+  Hash from_nasal_helper(naContext c, naRef ref, const Hash*)
+  {
+    if( !naIsHash(ref) )
+      throw bad_nasal_cast("Not a hash");
+
+    return Hash(ref, c);
+  }
+
+  //----------------------------------------------------------------------------
+  String from_nasal_helper(naContext c, naRef ref, const String*)
+  {
+    if( !naIsString(ref) )
+      throw bad_nasal_cast("Not a string");
+
+    return String(ref);
+  }
+
+} // namespace nasal
diff --git a/simgear/nasal/cppbind/detail/from_nasal_helper.hxx b/simgear/nasal/cppbind/detail/from_nasal_helper.hxx
new file mode 100644 (file)
index 0000000..865bc8d
--- /dev/null
@@ -0,0 +1,148 @@
+///@file
+/// 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_HELPER_HXX_
+#define SG_FROM_NASAL_HELPER_HXX_
+
+#include "nasal_traits.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>
+
+class SGPath;
+
+namespace nasal
+{
+  class Hash;
+  class String;
+
+  /**
+   * Thrown when converting a type from/to Nasal has failed
+   */
+  class bad_nasal_cast:
+    public std::bad_cast
+  {
+    public:
+      /**
+       * Construct with generic error message
+       */
+      bad_nasal_cast();
+
+      /**
+       * Construct from an error message
+       *
+       * @param msg Error message/description
+       */
+      explicit bad_nasal_cast(const std::string& msg);
+
+      virtual ~bad_nasal_cast() throw();
+
+      /**
+       * Get a description of the cause of the failed cast.
+       */
+      virtual const char* what() const throw();
+
+    protected:
+      std::string _msg;
+  };
+
+  /**
+   * Simple pass through for unified handling also of naRef.
+   */
+  inline naRef from_nasal_helper(naContext, naRef ref, const naRef*)
+  { return ref; }
+
+  /**
+   * Convert Nasal string to std::string
+   */
+  std::string from_nasal_helper(naContext c, naRef ref, const std::string*);
+
+  /**
+   * Convert a Nasal string to an SGPath
+   */
+  SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*);
+
+  /**
+   * Convert a Nasal hash to a nasal::Hash
+   */
+  Hash from_nasal_helper(naContext c, naRef ref, const Hash*);
+
+  /**
+   * Convert a Nasal string to a nasal::String
+   */
+  String from_nasal_helper(naContext c, naRef ref, const String*);
+
+  /**
+   * Convert a Nasal number to a C++ numeric type
+   */
+  template<class T>
+  typename boost::enable_if< boost::is_arithmetic<T>,
+                             T
+                           >::type
+  from_nasal_helper(naContext c, naRef ref, const 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 T>
+  std::vector<T>
+  from_nasal_helper(naContext c, naRef ref, const std::vector<T>*)
+  {
+    if( !naIsVector(ref) )
+      throw bad_nasal_cast("Not a vector");
+
+    int size = naVec_size(ref);
+    std::vector<T> vec(size);
+
+    for(int i = 0; i < size; ++i)
+      vec[i] = from_nasal_helper(c, naVec_get(ref, i), static_cast<T*>(0));
+
+    return vec;
+  }
+
+  /**
+   * Convert a Nasal vector of 2 elements to a 2d vector
+   */
+  template<class Vec2>
+  typename boost::enable_if<is_vec2<Vec2>, Vec2>::type
+  from_nasal_helper(naContext c, naRef ref, const Vec2*)
+  {
+    std::vector<double> vec =
+      from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0));
+    if( vec.size() != 2 )
+      throw bad_nasal_cast("Expected vector with two elements");
+    return Vec2(vec[0], vec[1]);
+  }
+
+} // namespace nasal
+
+#endif /* SG_FROM_NASAL_HELPER_HXX_ */
diff --git a/simgear/nasal/cppbind/detail/nasal_traits.hxx b/simgear/nasal/cppbind/detail/nasal_traits.hxx
new file mode 100644 (file)
index 0000000..2e21630
--- /dev/null
@@ -0,0 +1,58 @@
+///@file
+/// Type traits used for converting from and to Nasal 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_NASAL_TRAITS_HXX_
+#define SG_NASAL_TRAITS_HXX_
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace nasal
+{
+  template<class T>
+  struct is_vec2: public boost::integral_constant<bool, false> {};
+
+#define SG_MAKE_TRAIT(templ,type,attr)\
+  template templ\
+  struct attr< type >:\
+    public boost::integral_constant<bool, true> {};
+
+#ifdef SGVec2_H
+  SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2)
+#endif
+
+#ifdef OSG_VEC2B
+  SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2)
+#endif
+
+#ifdef OSG_VEC2D
+  SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2)
+#endif
+
+#ifdef OSG_VEC2F
+  SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2)
+#endif
+
+#ifdef OSG_VEC2S
+  SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
+#endif
+
+#undef SG_MAKE_TRAIT
+
+} // namespace nasal
+#endif /* SG_NASAL_TRAITS_HXX_ */
diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx
new file mode 100644 (file)
index 0000000..bc1f25e
--- /dev/null
@@ -0,0 +1,63 @@
+// Conversion functions to convert C++ types to Nasal 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 "to_nasal_helper.hxx"
+#include <simgear/nasal/cppbind/NasalHash.hxx>
+
+#include <simgear/misc/sg_path.hxx>
+
+namespace nasal
+{
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, const std::string& str)
+  {
+    naRef ret = naNewString(c);
+    naStr_fromdata(ret, str.c_str(), str.size());
+    return ret;
+  }
+
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, const char* str)
+  {
+    return to_nasal_helper(c, std::string(str));
+  }
+
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, naCFunction func)
+  {
+    return naNewFunc(c, naNewCCode(c, func));
+  }
+
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, const Hash& hash)
+  {
+    return hash.get_naRef();
+  }
+
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, const naRef& ref)
+  {
+    return ref;
+  }
+
+  //----------------------------------------------------------------------------
+  naRef to_nasal_helper(naContext c, const SGPath& path)
+  {
+    return to_nasal_helper(c, path.str());
+  }
+} // namespace nasal
diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.hxx b/simgear/nasal/cppbind/detail/to_nasal_helper.hxx
new file mode 100644 (file)
index 0000000..e367e00
--- /dev/null
@@ -0,0 +1,163 @@
+///@file
+/// Conversion helpers used by to_nasal<T>(naContext, T)
+///
+// 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_TO_NASAL_HELPER_HXX_
+#define SG_TO_NASAL_HELPER_HXX_
+
+#include "nasal_traits.hxx"
+
+#include <simgear/nasal/nasal.h>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/call_traits.hpp>
+#include <boost/type_traits.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+class SGPath;
+
+namespace nasal
+{
+  class Hash;
+
+  /**
+   * Convert std::string to Nasal string
+   */
+  naRef to_nasal_helper(naContext c, const std::string& str);
+
+  /**
+   * Convert C-string to Nasal string
+   */
+  // We need this to prevent the array overload of to_nasal being called
+  naRef to_nasal_helper(naContext c, const char* str);
+
+  /**
+   * Convert function pointer to Nasal function
+   */
+  naRef to_nasal_helper(naContext c, naCFunction func);
+
+  /**
+   * Convert a nasal::Hash to a Nasal hash
+   */
+  naRef to_nasal_helper(naContext c, const Hash& hash);
+
+  /**
+   * Simple pass-through of naRef types to allow generic usage of to_nasal
+   */
+  naRef to_nasal_helper(naContext c, const naRef& ref);
+
+  naRef to_nasal_helper(naContext c, const SGPath& path);
+
+  /**
+   * Convert a numeric type to Nasal number
+   */
+  template<class T>
+  typename boost::enable_if< boost::is_arithmetic<T>, naRef >::type
+  to_nasal_helper(naContext c, T num)
+  {
+    return naNum(num);
+  }
+
+  /**
+   * Convert a 2d vector to Nasal vector with 2 elements
+   */
+  template<class Vec2>
+  typename boost::enable_if<is_vec2<Vec2>, naRef>::type
+  to_nasal_helper(naContext c, const Vec2& vec);
+
+  /**
+   * Convert a std::map to a Nasal Hash
+   */
+  template<class Value>
+  naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map);
+
+  /**
+   * Convert a fixed size array to a Nasal vector
+   */
+  template<class T, size_t N>
+  naRef to_nasal_helper(naContext c, const T(&array)[N]);
+
+  /**
+   * Convert std::vector to Nasal vector
+   */
+  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_helper(naContext c, const Vector<T, Alloc>& vec)
+  {
+    naRef ret = naNewVector(c);
+    naVec_setsize(c, ret, vec.size());
+    for(size_t i = 0; i < vec.size(); ++i)
+      naVec_set(ret, i, to_nasal_helper(c, vec[i]));
+    return ret;
+  }
+
+  //----------------------------------------------------------------------------
+  template<class Vec2>
+  typename boost::enable_if<is_vec2<Vec2>, naRef>::type
+  to_nasal_helper(naContext c, const Vec2& vec)
+  {
+    // We take just double because in Nasal every number is represented as
+    // double
+    double nasal_vec[2] = {vec[0], vec[1]};
+    return to_nasal_helper(c, nasal_vec);
+  }
+
+  //----------------------------------------------------------------------------
+  template<class Value>
+  naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map)
+  {
+    naRef hash = naNewHash(c);
+
+    typedef typename boost::call_traits<Value>::param_type param_type;
+    typedef typename std::map<std::string, Value>::const_iterator map_iterator;
+
+    for( map_iterator it = map.begin(); it != map.end(); ++it )
+      naHash_set
+      (
+        hash,
+        to_nasal_helper(c, it->first),
+        to_nasal_helper(c, static_cast<param_type>(it->second))
+      );
+
+    return hash;
+  }
+
+  //----------------------------------------------------------------------------
+  template<class T, size_t N>
+  naRef to_nasal_helper(naContext c, const T(&array)[N])
+  {
+    naRef ret = naNewVector(c);
+    naVec_setsize(c, ret, N);
+    for(size_t i = 0; i < N; ++i)
+      naVec_set(ret, i, to_nasal_helper(c, array[i]));
+    return ret;
+  }
+
+} // namespace nasal
+
+#endif /* SG_TO_NASAL_HELPER_HXX_ */
diff --git a/simgear/nasal/cppbind/from_nasal.cxx b/simgear/nasal/cppbind/from_nasal.cxx
deleted file mode 100644 (file)
index bed08e4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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"
-#include "NasalString.hxx"
-
-#include <simgear/misc/sg_path.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_helper(naContext c, naRef ref, const std::string*)
-  {
-    naRef na_str = naStringValue(c, ref);
-    return std::string(naStr_data(na_str), naStr_len(na_str));
-  }
-
-  //----------------------------------------------------------------------------
-  SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*)
-  {
-      naRef na_str = naStringValue(c, ref);
-      return SGPath(std::string(naStr_data(na_str), naStr_len(na_str)));
-  }
-
-  //----------------------------------------------------------------------------
-  Hash from_nasal_helper(naContext c, naRef ref, const Hash*)
-  {
-    if( !naIsHash(ref) )
-      throw bad_nasal_cast("Not a hash");
-
-    return Hash(ref, c);
-  }
-
-  //----------------------------------------------------------------------------
-  String from_nasal_helper(naContext c, naRef ref, const String*)
-  {
-    if( !naIsString(ref) )
-      throw bad_nasal_cast("Not a string");
-
-    return String(ref);
-  }
-
-} // namespace nasal
index de1521355b43f6adcefefb0f80a9e3ab85b517c9..fe672c0178a1dcd56240571a11846134c70f8313 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef SG_FROM_NASAL_HXX_
 #define SG_FROM_NASAL_HXX_
 
-#include "from_nasal_detail.hxx"
+#include <simgear/nasal/cppbind/detail/from_nasal_helper.hxx>
 
 namespace nasal
 {
diff --git a/simgear/nasal/cppbind/from_nasal_detail.hxx b/simgear/nasal/cppbind/from_nasal_detail.hxx
deleted file mode 100644 (file)
index 6ff72f2..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-///@file
-/// 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 "nasal_traits.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>
-
-class SGPath;
-
-namespace nasal
-{
-  class Hash;
-  class String;
-
-  /**
-   * Thrown when converting a type from/to Nasal has failed
-   */
-  class bad_nasal_cast:
-    public std::bad_cast
-  {
-    public:
-      /**
-       * Construct with generic error message
-       */
-      bad_nasal_cast();
-
-      /**
-       * Construct from an error message
-       *
-       * @param msg Error message/description
-       */
-      explicit bad_nasal_cast(const std::string& msg);
-
-      virtual ~bad_nasal_cast() throw();
-
-      /**
-       * Get a description of the cause of the failed cast.
-       */
-      virtual const char* what() const throw();
-
-    protected:
-      std::string _msg;
-  };
-
-  /**
-   * Simple pass through for unified handling also of naRef.
-   */
-  inline naRef from_nasal_helper(naContext, naRef ref, const naRef*)
-  { return ref; }
-
-  /**
-   * Convert Nasal string to std::string
-   */
-  std::string from_nasal_helper(naContext c, naRef ref, const std::string*);
-
-  /**
-   * Convert a Nasal string to an SGPath
-   */
-  SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*);
-
-  /**
-   * Convert a Nasal hash to a nasal::Hash
-   */
-  Hash from_nasal_helper(naContext c, naRef ref, const Hash*);
-
-  /**
-   * Convert a Nasal string to a nasal::String
-   */
-  String from_nasal_helper(naContext c, naRef ref, const String*);
-
-  /**
-   * Convert a Nasal number to a C++ numeric type
-   */
-  template<class T>
-  typename boost::enable_if< boost::is_arithmetic<T>,
-                             T
-                           >::type
-  from_nasal_helper(naContext c, naRef ref, const 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 T>
-  std::vector<T>
-  from_nasal_helper(naContext c, naRef ref, const std::vector<T>*)
-  {
-    if( !naIsVector(ref) )
-      throw bad_nasal_cast("Not a vector");
-
-    int size = naVec_size(ref);
-    std::vector<T> vec(size);
-
-    for(int i = 0; i < size; ++i)
-      vec[i] = from_nasal_helper(c, naVec_get(ref, i), static_cast<T*>(0));
-
-    return vec;
-  }
-
-  /**
-   * Convert a Nasal vector of 2 elements to a 2d vector
-   */
-  template<class Vec2>
-  typename boost::enable_if<is_vec2<Vec2>, Vec2>::type
-  from_nasal_helper(naContext c, naRef ref, const Vec2*)
-  {
-    std::vector<double> vec =
-      from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0));
-    if( vec.size() != 2 )
-      throw bad_nasal_cast("Expected vector with two elements");
-    return Vec2(vec[0], vec[1]);
-  }
-
-} // namespace nasal
-
-#endif /* SG_FROM_NASAL_DETAIL_HXX_ */
diff --git a/simgear/nasal/cppbind/nasal_traits.hxx b/simgear/nasal/cppbind/nasal_traits.hxx
deleted file mode 100644 (file)
index 2e21630..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-///@file
-/// Type traits used for converting from and to Nasal 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_NASAL_TRAITS_HXX_
-#define SG_NASAL_TRAITS_HXX_
-
-#include <boost/type_traits/integral_constant.hpp>
-
-namespace nasal
-{
-  template<class T>
-  struct is_vec2: public boost::integral_constant<bool, false> {};
-
-#define SG_MAKE_TRAIT(templ,type,attr)\
-  template templ\
-  struct attr< type >:\
-    public boost::integral_constant<bool, true> {};
-
-#ifdef SGVec2_H
-  SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2)
-#endif
-
-#ifdef OSG_VEC2B
-  SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2)
-#endif
-
-#ifdef OSG_VEC2D
-  SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2)
-#endif
-
-#ifdef OSG_VEC2F
-  SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2)
-#endif
-
-#ifdef OSG_VEC2S
-  SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
-#endif
-
-#undef SG_MAKE_TRAIT
-
-} // namespace nasal
-#endif /* SG_NASAL_TRAITS_HXX_ */
diff --git a/simgear/nasal/cppbind/to_nasal.cxx b/simgear/nasal/cppbind/to_nasal.cxx
deleted file mode 100644 (file)
index b5224ad..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Conversion functions to convert C++ types to Nasal 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 "to_nasal.hxx"
-#include "NasalHash.hxx"
-
-#include <simgear/misc/sg_path.hxx>
-
-namespace nasal
-{
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, const std::string& str)
-  {
-    naRef ret = naNewString(c);
-    naStr_fromdata(ret, str.c_str(), str.size());
-    return ret;
-  }
-
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, const char* str)
-  {
-    return to_nasal(c, std::string(str));
-  }
-
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, naCFunction func)
-  {
-    return naNewFunc(c, naNewCCode(c, func));
-  }
-
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, const Hash& hash)
-  {
-    return hash.get_naRef();
-  }
-
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, const naRef& ref)
-  {
-    return ref;
-  }
-
-  //----------------------------------------------------------------------------
-  naRef to_nasal(naContext c, const SGPath& path)
-  {
-    return to_nasal(c, path.str());
-  }
-} // namespace nasal
index eeaf5a97475a5849b69f95f04dbd826ab3690dc3..8d1437d1d3873c7864b19815306ec0dc221f26dc 100644 (file)
 #ifndef SG_TO_NASAL_HXX_
 #define SG_TO_NASAL_HXX_
 
-#include "nasal_traits.hxx"
-
-#include <simgear/nasal/nasal.h>
-
-#include <boost/utility/enable_if.hpp>
-#include <boost/call_traits.hpp>
-#include <boost/type_traits.hpp>
-
-#include <map>
-#include <string>
-#include <vector>
-
-class SGPath;
+#include <simgear/nasal/cppbind/detail/to_nasal_helper.hxx>
 
 namespace nasal
 {
-  class Hash;
-
-  /**
-   * Convert std::string to Nasal string
-   */
-  naRef to_nasal(naContext c, const std::string& str);
-
-  /**
-   * Convert C-string to Nasal string
-   */
-  // We need this to prevent the array overload of to_nasal being called
-  naRef to_nasal(naContext c, const char* str);
-
-  /**
-   * Convert function pointer to Nasal function
-   */
-  naRef to_nasal(naContext c, naCFunction func);
-
-  /**
-   * Convert a nasal::Hash to a Nasal hash
-   */
-  naRef to_nasal(naContext c, const Hash& hash);
-
-  /**
-   * Simple pass-through of naRef types to allow generic usage of to_nasal
-   */
-  naRef to_nasal(naContext c, const naRef& ref);
-
-  naRef to_nasal(naContext c, const SGPath& path);
-    
   /**
-   * Convert a numeric type to Nasal number
+   * Convert any supported C++ type to Nasal.
+   *
+   * @param c   Active Nasal context
+   * @param arg C++ Object to be converted
+   * @tparam T  Type of converted object
+   *
+   * @throws bad_nasal_cast if conversion is not possible
+   *
+   * @note  Every type which should be supported needs a function with the
+   *        following signature declared (Type needs to be a const reference
+   *        for non-integral types):
+   *
+   *        naRef to_nasal_helper(naContext, Type)
    */
   template<class T>
-  typename boost::enable_if< boost::is_arithmetic<T>, naRef >::type
-  to_nasal(naContext c, T num)
+  naRef to_nasal(naContext c, T arg)
   {
-    return naNum(num);
+    return to_nasal_helper(c, arg);
   }
 
-  /**
-   * Convert a 2d vector to Nasal vector with 2 elements
-   */
-  template<class Vec2>
-  typename boost::enable_if<is_vec2<Vec2>, naRef>::type
-  to_nasal(naContext c, const Vec2& vec);
-
-  /**
-   * Convert a std::map to a Nasal Hash
-   */
-  template<class Value>
-  naRef to_nasal(naContext c, const std::map<std::string, Value>& map);
-
-  /**
-   * Convert a fixed size array to a Nasal vector
-   */
   template<class T, size_t N>
-  naRef to_nasal(naContext c, const T(&array)[N]);
-
-  /**
-   * Convert std::vector to Nasal vector
-   */
-  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 to_nasal(naContext c, const T(&array)[N])
   {
-    naRef ret = naNewVector(c);
-    naVec_setsize(c, ret, vec.size());
-    for(size_t i = 0; i < vec.size(); ++i)
-      naVec_set(ret, i, to_nasal(c, vec[i]));
-    return ret;
+    return to_nasal_helper(c, array);
   }
 
   /**
@@ -128,52 +63,9 @@ namespace nasal
 
     static type get()
     {
-      return static_cast<type>(&to_nasal);
+      return &to_nasal<param_type>;
     }
   };
-
-  //----------------------------------------------------------------------------
-  template<class Vec2>
-  typename boost::enable_if<is_vec2<Vec2>, naRef>::type
-  to_nasal(naContext c, const Vec2& vec)
-  {
-    // We take just double because in Nasal every number is represented as
-    // double
-    double nasal_vec[2] = {vec[0], vec[1]};
-    return to_nasal(c, nasal_vec);
-  }
-
-  //----------------------------------------------------------------------------
-  template<class Value>
-  naRef to_nasal(naContext c, const std::map<std::string, Value>& map)
-  {
-    naRef hash = naNewHash(c);
-
-    typedef typename boost::call_traits<Value>::param_type param_type;
-    typedef typename std::map<std::string, Value>::const_iterator map_iterator;
-
-    for( map_iterator it = map.begin(); it != map.end(); ++it )
-      naHash_set
-      (
-        hash,
-        to_nasal(c, it->first),
-        to_nasal(c, static_cast<param_type>(it->second))
-      );
-
-    return hash;
-  }
-
-  //----------------------------------------------------------------------------
-  template<class T, size_t N>
-  naRef to_nasal(naContext c, const T(&array)[N])
-  {
-    naRef ret = naNewVector(c);
-    naVec_setsize(c, ret, N);
-    for(size_t i = 0; i < N; ++i)
-      naVec_set(ret, i, to_nasal(c, array[i]));
-    return ret;
-  }
-
 } // namespace nasal
 
 #endif /* SG_TO_NASAL_HXX_ */