Comments (26)
I am able to reproduce this by modifying simple.cpp
a bit. The argument type of a function cannot be a pointer to std::string. For example, suppose I change the hasBigFeet
function in ponder/test/examples/simple.cpp
as follows.
bool hasBigFeet(std::string* dummy) const { return shoeSize > 10; }
Then compiling simple.cpp
would have the following error.
[ 91%] Building CXX object test/examples/CMakeFiles/egtest.dir/simple.cpp.o
In file included from include/ponder/classget.hpp:38:0,
from include/ponder/classbuilder.hpp:35,
from ponder/test/examples/simple.cpp:33:
include/ponder/detail/typeid.hpp: In instantiation of static const char* ponder::detail::StaticTypeId<T>::get(bool) [with T = std::basic_string<char>] :
include/ponder/class.inl:56:60: required from static ponder::ClassBuilder<T> ponder::Class::declare(ponder::IdRef) [with T = std::basic_string<char>; ponder::IdRef = ponder::detail::basic_string_view<char>]
ponder/test/examples/simple.cpp:67:47: required from here
include/ponder/detail/typeid.hpp:52:46: error: PONDER_TYPE_NOT_REGISTERED is not a member of std::basic_string<char>
return T::PONDER_TYPE_NOT_REGISTERED();
^
make[2]: *** [test/examples/CMakeFiles/egtest.dir/simple.cpp.o] Error 1
make[1]: *** [test/examples/CMakeFiles/egtest.dir/all] Error 2
make: *** [all] Error 2
This compilation error can be avoid by declaring PONDER_TYPE(std::string)
.
However running egtest with this code would throw the classNotFound exception on class type std::string
.
$ egtest
------------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
egtest is a Catch v2.2.2 host application.
Run with -? for options
-------------------------------------------------------------------------------
simple tests
intro
-------------------------------------------------------------------------------
ponder/test/examples/simple.cpp:117
...............................................................................
/scratch/backup/ponder/test/examples/simple.cpp:117: FAILED:
**due to unexpected exception with message:
the metaclass std::string couldn't be found**
Class Vec2D: 2D vector
add: add vector to this and return result
===============================================================================
test cases: 3 | 2 passed | 1 failed
assertions: 1 | 1 failed
Not that this is the only way to do pass by reference for a string. As reported in a one of the previous issues, using string& would not work because it acts like pass by value in both CAMP and PONDER.
I am trying to port a project which used CAMP to PONDER. Because of this, I am basically stuck.
from ponder.
Ok, I'll have some time this weekend. I'll take a look. 👍
from ponder.
Thanks, Billy. Another note. In CAMP, to get rid of this runtime error, I had to also add the following line.
Class::declarestd::string("String");
But this did not work for PONDER.
Basically I need a metaclass function to be able to do call by reference, either by string& or string*. Otherwise the function defined becomes useless for me.
from ponder.
Which platform, compiler, and versions please. I am currently unable to reproduce this.
from ponder.
Red Hat Linux g++ 4.8.5.
from ponder.
Ok, on the CI tests, gcc 4.8.4 passes: https://travis-ci.org/billyquith/ponder/jobs/456345131
from ponder.
Are you able to test on a more recent version of the compiler? 4.8.5 is from 2015. I have experienced bugs with GCC before.
from ponder.
Sure. I will give it a try. Thanks
from ponder.
One question. Is using ninja to build ponder absolutely required? I had a hard time installing ninja and dnf on my system. I simply used "cmake . && make" to make ponder and it completed with no error.
from ponder.
No you can use any build system. I just used Ninja for the example.
from ponder.
I reproduced this on OSX (Mac) using ninja to build as well. My changes in test/examples/simple.cpp are as follows:
37,38d36
< PONDER_TYPE(std::string)
<
57c55
< bool hasBigFeet(std::string* dummy) const { return shoeSize > 10; } // U.K.!
---
> bool hasBigFeet() const { return shoeSize > 10; } // U.K.!
69,70d66
< ponder::Class::declare<std::string>("String");
<
103,104c99
< std::string dummy = "dummy";
< const bool bigFeet = ponder::runtime::call(func, person, &dummy).to<bool>();
---
> const bool bigFeet = ponder::runtime::call(func, person).to<bool>();
Platform and compiler are OSX Apple LLVM version 9.1.0 (clang-902.0.39.2).
from ponder.
from ponder.
I attached my modified complete simple.cpp above. Please help to see if it reproduces in your system.
Thanks,
from ponder.
Why are you trying to register std::string
? Do you need to do this? It is a basic type, handled by ponder::Value
. You don't need to register it to use it. I'm just trying to understand why you need to do this.
from ponder.
As I mentioned earlier, if I did not register it, the code would not compile. If the function's argument type is the basic pass by value type std::string, I did not have to register. For the pointer type std::string*, I had to for some reason. For the reference type std::string&, it was a whole different issue and the registration did not help either.
from ponder.
I think I figure out where the issue is. It comes down to the difference in declaring a metaclass between CAMP and PONDER. In CAMP, it is defined as follows.
static ClassBuilder declare(const std::string& name)
A metaclass declared can be given an arbitrary name as long as it is unique.
Ponder declares it as follows.
static ClassBuilder ponder::Class::declare (IdRef id = ponder::Id())
It does not allow a metaclass declared to be given an arbitrary name. Based on the implementation of detail::ClassManager::addClass(), the name given should be either empty or be the same as the C++ class typename.
That is, if I declare the metaclass std::string as
ponder::Class::declarestd::string("");
or
ponder::Class::declarestd::string("std::string");
The simple.cpp code I attached above would run fine.
from ponder.
It ran fine after I registered and metaclass declared std::string. But after that the ponder::Value::kind() for std::string return type ponder::User instead of ponder::String. Do you know why and a workaround?
Thanks,
from ponder.
I wonder if you have reproduced this problem and know a solution for it?
from ponder.
Sorry, I was on holiday. ⛅️
I did have a look and I think the problem is that ponder::Value
does not handle referencing types for the value types that it holds (e.g. pointers). I haven't checked whether CAMP did. This may be something that got lost in the refactoring. I did look into fixing this, but I didn't come up with a satisfactory solution yet. I'll try and have another look this week. This should be something you should be able to do.
Your workaround is to register std::string
as a user type so that the reference is dealt with as a UserData
. This has different implementations for reference and value semantics, whereas Value
, for non-UserData
types, does not.
std::string s;
foo(&s); // void foo(std::string*);
In the above call, at the point of setting the argument, we can dereference s
, but when we want to set the value, we have lost the reference. This is the problem that needs solving.
from ponder.
Welcome back and thanks for your help as always. For CAMP, if I need to use any reference simple type, such as int or string, as a function argument, I also need to register the simple type. However CAMP is able to preserve the simple type in Value. The simple type after registration is lost in Ponder. It becomes the User type and as a result I am not able to convert it back to the simple type. The conversion would throw an exception, similar to the following:
value of type user couldn't be converted to type int
from ponder.
I want to add that once I registered the simple type, any property getter which returns this simple type becomes a User type. This seems to already happen at the class declaration time when the property is added to the class builder. If I do not register the simple type, then the property getter returning type is correct. But I had to do the registration to get the code compiled and run. With a User type, I won't be able to retrieve the property value back to the simple type. This is the dilemma that I am facing.
from ponder.
I spent some time to track down the reason for this behavior to the following AccessTraits
definition in propertyfactory.hpp
.
template <typename T>
struct AccessTraits<T,
typename std::enable_if<StaticTypeId<T>::defined && !std::is_enum<T>::value>::type>
{
static constexpr PropertyAccessKind kind = PropertyAccessKind::User;
...
This says if a type, including any basic type, is registered as a ponder type, it is automatically considered as a user defined type. I guess we could exclude some C++ basic types in the Boolean expression of enable_if().
from ponder.
I want to add that once I registered the simple type, any property getter which returns this simple type becomes a User type.
This says if a type, including any basic type, is registered as a ponder type, it is automatically considered as a user defined type.
I think I would rather not allow basic types (handled by Value
) to be registered as UserType
s. If Values could also be referenced then this would not be necessary. Currently you can only return parameter values by reference for UserTypes, e.g. void foo(Type*)
and not void foo(int*)
, but it would be nice to be able to do so.
The change you are suggesting would allow basic types to be passed as UserTypes, but I think there would be complications where this turns out to be ambiguous. One solution is to add pointer versions of the basic types to value (assuming that they are all references, and not owned).
from ponder.
I agree . The best fix is to allow to use pointer to a basic type without having to register that basic type as a User type. I am not sure if defining ValueMapper<T*> would make that happen. But I am happy to find a solution by modifying the AccessTraits. Note that CAMP works exactly like this. To use a pointer type to a basic type, you need to register that basic type and declare it as a metaclass.
from ponder.
I created two new issues which summarize the discussions in this thread.
from ponder.
I'll close this issue as we created two other issues. V3.1 is now released which fixes one of those issues. The other issue is covered in #109.
from ponder.
Related Issues (20)
- Failed to build Lua example HOT 3
- ponder::Value's comparison operators are not complete HOT 4
- missing a return statement in string_view.hpp at line 215 HOT 1
- Creating UserObject via class name does not work HOT 5
- call by reference, using a pointer or a non-const reference, does not work HOT 18
- Having problems to get the property value of a user defined type HOT 6
- Interest for registration of template types? HOT 4
- Deprecate MSVC 2015 HOT 1
- support inherit for lua?
- Class properties do not respect ValueMappers HOT 1
- How to properly set nested UserObjects? HOT 1
- Ponder compile failed with a future version of MSVC HOT 6
- Building Error HOT 1
- Replace exceptions with tryGet
- Use runtime error HOT 2
- Destroy object causes a runtime failure
- How to build and user ponder with windows7? HOT 3
- Execute function of class by class name as string
- Unable to compile under ubuntu 22.04 LTS without two file changes in util.cpp and catch.hpp
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ponder.