Add from_nasal helper and fix to_nasal for std::vector.

This commit is contained in:
Thomas Geymayer
2012-11-10 14:18:27 +01:00
parent a9b45967ce
commit 0fef94cfdb
6 changed files with 242 additions and 5 deletions

View 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
)

View 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);

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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_ */

View 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());