c++ parse from string using template - string

In C++, I want to get value from string.
I know there are functions like stoi, stol, stof...
But can I write a function that includes all of them? like using a template to infer the data type?
template<typename T>
T fromString(const std::string& s){
// do something here
// call stoi, stof according to typename T
}
string si = "1234";
int integer = fromString<int>(si);
string sf = "1234.1234";
float float_point = fromString<float>(sf);

Cannot comment yet, hence this ...
Not clear if you're looking for a single function, or templated (overloaded) functions? This would work: Have no default implementation with return type T, and specializations / usage so:
template<typename T> foo(const std::string& str) {}
template<> int foo(const std::string& str) {return atoi(str.c_str());}
template<> double foo(const std::string& str) {return atof(str.c_str());}
...
const std::string str1("1234"); const std::string str2("12.34");
const auto iVal = foo<int>(str1);
const auto dVal = foo<double>(str2);
Note the absence of specialization in the function name with the template function specialization, of course it appears as a return type.

Related

error compiling lua bridge

i was trying the compile lua bridge from the repository
https://github.com/vinniefalco/LuaBridge/releases
However was getting the error
C2953 'luabridge::FuncTraits': class template has already been defined LuaBridgeDemo luabridgedemo-1.0\luabridgedemo-1.0\luabridge\luabridge.h 1436
Upon closer examination there are two similar structures declared on the header file
template <typename R, typename D>
struct FuncTraits <R (*) () THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef None Params;
static R call (DeclType fp, TypeListValues <Params> const&)
{
return fp ();
}
};
template <class T, typename R, typename D>
struct FuncTraits <R (T::*) () const THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef None Params;
static R call (T const* const obj, DeclType fp, TypeListValues <Params> const&)
{
(void)tvl;
return (obj->*fp)();
}
};
I am using Visual C++ 2015. Is there any setting or code change that I need to do to resolve this error.
Thanks in advance
I just removed the duplicate method signatures, it compiled after that.

Auto-interpreting a c-style string as a std::string via Boost's Property tree's .get function

I use boosts property tree, included via
#include "boost\property_tree\ptree.hpp"
And... I'd like to create a simple function which substitutes a value in case none is found via a fairly straight-forward template function:
template <typename Type>
Type getValueOrDefault( std::string const& str, Type defaultValue )
{
Type returnValue = defaultValue;
try {
returnValue = mSettings.get<Type>( str );
}
catch ( boost::property_tree::ptree_error &e )
{
// Log error!
}
return returnValue;
}
This works well in principle, but runs into a bit problems if I rely on C-style string. For example, calling the function as follows:
getValueOrDefault( "pathToImportantStuffParameter", "c:/defaultdir/" )
will result in the following error:
boost\property_tree\stream_translator.hpp(36): error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::basic_istream<char,std::char_traits<char>>' (or there is no acceptable conversion)
The error stems from passing char const * as a template parameter which makes a fair bit of sense. Two obvious solutions to this issue would be to force the default value to be a std::string object, like so:
getValueOrDefault<std::string>( "pathToImportantStuffParameter", "c:/defaultdir/" )
getValueOrDefault( "pathToImportantStuffParameter", std::string("c:/defaultdir/") )
But I'm wondering if someone might know of some template magic I could sprinkle to automatically interpret c-style strings as std::strings?
You can provide a char array overload which converts the char array to a std::string and then calls the default implementation:
#include <iostream>
#include <string>
template <typename T>
T getValueOrDefault(const std::string& str, T&& defaultValue)
{
std::cout << "inside default implementation" << std::endl;
/* ... */
return defaultValue;
}
template <std::size_t N>
std::string getValueOrDefault(const std::string& str, const char (&defaultValue)[N])
{
std::cout << "inside char[] overload" << std::endl;
return getValueOrDefault(str, std::string(defaultValue));
}
int main()
{
auto x = getValueOrDefault("foo", "bar");
return 0;
}
live example
An alternative solution is to use custom type traits:
#include <string>
#include <type_traits>
template <typename T>
struct return_type
{
using type = T;
};
template <>
struct return_type<const char*>
{
using type = std::string;
};
template <typename T>
using return_type_t = typename return_type<typename std::decay<T>::type>::type;
template <typename T>
return_type_t<T> getValueOrDefault(const std::string& str, T&& defaultValue)
{
return_type_t<T> value(defaultValue);
/* ... */
return value;
}
int main()
{
auto x = getValueOrDefault("foo", "bar");
static_assert(std::is_same<decltype(x), std::string>::value, "");
return 0;
}
live example
The only way I found is to specialize getValueOrDefault for const char*, which calls getValueOrDefault with std::string explicitly:
//Note that the return value is unspecified, it returns a 'const char*' to a temporary,
//which will be destroyed when the function returns
template <>
const char* getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string>(str, defaultValue).c_str();
}
If you want to that function to return a std::string instead of an invalid const char*, you have to change the template signature a bit:
//Default return type is the same as paramter
template <typename Type, typename Return = Type>
Return getValueOrDefault(std::string const& str, Type defaultValue)
{
//...
}
//Trick the compiler to select this overload for 'const char*'
template <typename Return = std::string>
Return getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string, std::string>(str, defaultValue);
}
or you could just plain overload the function (thanks #m.s.)
//Overload for 'const char*'
std::string getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string>(str, defaultValue);
}
There is also a third way (if you can use C++14), using the string literal ""s:
//"c:/defaultdir/"s is a std::string (note the s after it => string literal)
getValueOrDefault("pathToImportantStuffParameter", "c:/defaultdir/"s);

How to publish a constant string in the Rust FFI?

I want to have a Rust library expose a const char * static string to C, to be compatible with an existing interface (specifically librsync). That is, the C header file has
extern char const *my_string;
In C, the library would simply have
char const *my_string = "hi";
In Rust I've tried something like
pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char };
but this complains
error: casting `&'static str` as `*const i8` is invalid
It seems like I can't use CString etc because they won't be a compile-time constant expression.
We need a public, static, unmangled pointer to some zero-terminated bytes:
#[export_name = "CONST_C_STR"] // or #[no_mangle]
pub static CONST_C_STR: &[u8; 20] = b"a constant c string\0";
This worked with a simple C program:
#include <stdio.h>
extern char * CONST_C_STR;
int main(int argc, char *argv[]) {
printf("%s\n", CONST_C_STR);
}
The crate c_str_macro provides a convenience macro c_str!, which appends a 0 byte to a Rust string literal and presents it as a CStr reference.
Disclaimer: I'm the author of the crate.

Fitting string literals for different string classes

The problem
I am implementing a class where I want to let the user choose the string type (std::string, std::wstring, std::u16string, ...) via a template parameter. I currently fail to make the string literals fit the chosen string type: Once I decide for a literal prefix ("hello" vs. L"hello" vs. u"hello" vs. U"hello"), I get compilation errors for all incompatible string classes.
Toy example
As an example, consider the following code (compile with --std=c++11):
#include <string>
template<typename StringType>
void hello_string()
{
StringType result("hello");
}
int main()
{
// works
hello_string<std::string>();
hello_string<std::basic_string<char>>();
// the code below does not compile
hello_string<std::wstring>();
hello_string<std::basic_string<unsigned char>>();
hello_string<std::u16string>();
}
Function hello_string() shows the essence of what I want to do: have a string type as template parameter, and assign string literals to variables of this type.
Possible workaround
One way to overcome my problem would be to implement several specializations of the hello_string() function. The problem is that this would lead to several copies of each string literal - one for each string literal prefix. I think this is rather ugly, and there must be better way.
Another way could be to chose "normal" string literals as default values and have functions do a conversion to the different string types. While this would avoid code duplication, it would introduce unnecessary conversions of something that is actually constant.
You can make yourself a macro. First define a struct that wraps the char-choosing:
namespace details {
template<typename T>
struct templ_text;
template<>
struct templ_text <char>
{
typedef char char_type;
static const char_type * choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return narrow; }
static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return narrow; }
};
template<>
struct templ_text < wchar_t >
{
typedef wchar_t char_type;
static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return wide; }
static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return wide; }
};
template<>
struct templ_text < char16_t >
{
typedef char16_t char_type;
static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u16; }
static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u16; }
};
template<>
struct templ_text < char32_t >
{
typedef char32_t char_type;
static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u32; }
static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u32; }
};
}
Wrap it into a nice macro:
#define TEMPL_TEXT(Ch, txt) details::templ_text<Ch>::choose(txt, L##txt, u##txt, U##txt)
Then your function would be:
template<typename StringType>
void hello_string()
{
StringType result(TEMPL_TEXT(typename StringType::value_type, "Hello"));
}
I think that unused copies of the string will be optimized away.

Marshalling nested Structs in C to C#

I'm again stuck with marshalling C structs into C#. Here is what I want to marshal to C#.
The C function signature is as below
int GetParametersDescription(unsigned int *numParams,
OP_PARAMETER_INFO **parameterInfo,
unsigned int *numVars,
OP_VARIABLE_INFO **variableInfo);
Output Arguments
numParams: number of model’s parameters.
parameterInfo: List of parameters’ structures returned.Size of the list is numParams.
numVars: number of model’s variables.
variableInfo: List of variables’ structures returned.Size of the list is numVars.
OP_PARAMETER_INFO struct signature in C
typedef struct OP_PARAMETER_INFO {
unsigned id; // Parameter Id
char *path; // Parameter's path in the model
char *name; // Parameter's label if any
char *alias; // Parameter's alias if any.
struct OP_VARIABLE_INFO *varInfo; // Pointer on OP_VARIABLE_INFO if variable exist
unsigned nbRows; // Number of rows for this parameter
unsigned nbCols; // Number of cols for this parameter
double *values; // List of values, nbValue = nbRows * nbCols
OP_SEARCH_RESULTS exist; // This is an enum
unsigned newParamId; // ID of the estimated parameter if does not exist
} OP_PARAMETER_INFO;
OP_VARIABLE_INFO struct signature in C
typedef struct OP_VARIABLE_INFO {
unsigned id; // Variable Id
char *name; // Variable name
unsigned int nbParams; // Number of parameters associated with the variable
struct OP_PARAMETER_INFO** param; // List of pointers of OP_PARAMETER_INFO structure
} OP_VARIABLE_INFO;
OP_SEARCH_RESULTS is an enum and the signature look as below
typedef enum {
OP_SEARCH_NOT_FOUND,
OP_SEARCH_FOUND_EXACT,
OP_SEARCH_FOUND_DIFFERENT,
OP_SEARCH_FOUND_ESTIMATION
} OP_SEARCH_RESULTS;
I did try out making structs in C#, but none of them seem to work.
Could you pls help me defining these structs in C# and calling them in P/invoke methods and to extract the structs information.....

Resources