Is there any way to safely copy a bsoncxx document to another.
In following code I am not able to do that
class DocClass
{
private:
bsoncxx::builder::basic::document m_doc;
public:
bsoncxx::builder::basic::document& copy(bsoncxx::builder::basic::document& obj)
{
obj = m_doc; //Not allowed
//Error C2280 attempting to reference a deleted function
}
};
There should not be any harm to the object even after copy.
Please help.
Thanks,
Shibin
If you want to copy a bsoncxx::document::value, you can construct a new one from its view:
bsoncxx::document::value foo = ...;
bsoncxx::document::value bar{foo.view()};
bsoncxx::builder::basic::document is only movable, not copyable. However, you can get view to the underlying document from the builder with the view() method, which might be able to help you depending on your use cases. You'll still only be able to extract from the builder once though, so you'll have to rely on constructing a second document::value if you need more than one.
Related
I'm currently testing some simple AngelScript stuff, and noticed something I find a bit strange when it comes to how objects are initialized from classes.
Let's say I define a class like this:
class MyClass {
int i;
MyClass(int i) {
this.i = i;
}
}
I can create an object of this class by doing this:
MyClass obj = MyClass(5);
However it seems I can also create an object by doing this:
MyClass obj;
The problem here is that obj.i becomes a default value as it is undefined.
Additionally, adding a default constructor to my class and a print function call in each one reveals that when I do MyClass obj = MyClass(5); BOTH constructors are called, not just the one with the matching parameter. This seems risky to me, as it could initialize a lot of properties unnecessarily for this "ghost" instance.
I can avoid this double-initialization by using a handle, but this seems more like a work-around rather than a solution:
MyClass# obj = MyClass(5);
So my question sums up to:
Can I require a specific constructor to be called?
Can I prevent a default constructor from running?
What's the proper way to deal with required parameters when creating objects?
Mind that this is purely in the AngelScript script language, completely separate from the C++ code of the host application. The host is from 2010 and is not open-source, and my knowledge of their implementation is very limited, so if the issue lies there, I can't change it.
In order to declare class and send the value you choose to constructor try:
MyClass obj(5);
To prevent using default constructor create it and use:
.
MyClass()
{
abort("Trying to create uninitialized object of type that require init parameters");
}
or
{
exit(1);
}
or
{
assert(1>2,"Trying to create uninitialized object of type that require init parameters");
}
or
{
engine.Exit();
}
in case that any of those is working in you environment.
declaring the constructor as private seems not to work in AS, unlike other languages.
I have a object property in my Class which is private and marked as read-only.
private var readOnlyObj:Object;
I can only access it with a get method:
public function get readOnly(){ return readOnlyObj }
I can access it by:
var objClass = new MyClass();
trace(objClass.readOnly)
And if i'll try to modify it:
objClass.readOnly = new Object();
I'll get an error:
Error# Property is read only.
Now my question is:
How do I set the properties of my readOnlyObj as read-only?
If I have set the object in the constructor:
readOnlyObj["property1"] = 0;
And modify that property by:
objClass.readOnly["property1"] = 2;
It is valid. I want set the property1 to a read-only property. Is this possible? Thank You!
You can do this by returning a duplicate of the original object and not the object itself.
The transform properties of DisplayObjects work like this: you can get the object property from a get function and can modify the object, but such modification has no effect until you pass the modified object back to the set function.
In your case, there's no way to give the object back (no setter) and by returning a copy (commonly called 'clone') from the getter, there is no way to modify the object property from outside, because the returned reference reference the newly created independent clone, essentially making the internal object constant.
What you are asking is not possible and only yield the answer "no" if on the other hand you asked about how to achieve that functionality then there would be a few answer possible.
First of all given your code and the problem at hand it is clear that you misunderstand the class scope. You set:
private var readOnlyObj:Object;
As read only while it's really not the object you want to protect, it's its properties. So readOnlyObj should really not even be visible and accessible.
Now that readOnlyObj is private and not accessible, you can put together a simple method to retrieve properties:
public function getProperty(name:String):*
{
if(readOnlyObj[name] != undefined)
{
return readOnlyObj[name];
}
return null;
}
It might also be useful to know how to put together a public setter that cannot be used externally.
Create an internal Boolean variable (only with true package), then internally set that variable to true before setting the property then set it back to false. Since externally that boolean cannot be set you end up with a public setter that cannot be used externally.
internal var allowSetter:Boolean;
public function set whatever(value:*):void
{
if(allowSetter)
{
//set property ect...
allowSetter = false;
}
}
You can't really do this, at least in the way you describe. You can of course make your readOnly object a custom class instance that only has read-only properties, but you can't freeze a dynamic Object instance.
I found conception of Delegates pretty hard for me. I really do not understand why I can't simply pass one function to another and need to wrap it to Delegate. I read in docs that there is some cases when I do not know it's name and Delegate is only way to call it.
But now I have trouble in understanding conception of callbacks. I tried to find more information, but I can't understand is it's simply call of other function or what is it.
Could you show examples of D callbacks and explain where they can be helpful?
import vibe.d;
shared static this()
{
auto settings = new HTTPServerSettings;
settings.port = 8080;
listenHTTP(settings, &handleRequest);
}
void handleRequest(HTTPServerRequest req,
HTTPServerResponse res)
{
if (req.path == "/")
res.writeBody("Hello, World!", "text/plain");
}
&handleRequest is it callback? How it's work and at what moment it's start?
So within memory a function is just a pile of bytes. Like an array, you can take a pointer to it. This is a function pointer. It has a type of RETT function(ARGST) in D. Where RETT is the return type and ARGST are the argument types. Of course attributes can be applied like any function declaration.
Now delegates are a function pointer with a context pointer. A context pointer can be anything from a single integer (argument), call frame (function inside of another) or lastly a class/struct.
A delegate is very similar to a function pointer type at RETT delegate(ARGST). They are not interchangeable, but you can turn a function pointer into a delegate pointer pretty easily.
The concept of a callback is to say, hey I know you will know about X so when that happens please tell me about X by calling this function/delegate.
To answer your question about &handleRequest, yes it is a callback.
You can pass functions to other functions to later be called.
void test(){}
void receiver(void function() fn){
// call it like a normal function with 'fn()'
// or pass it around, save it, or ignore it
}
// main
receiver(&test); // 'test' will be available as 'fn' in 'receiver'
You need to prepend the function name as argument with & to clarify you want to pass a function pointer. If you don't do that, it will instead call that function due to UFCS (calling without braces). It is not a delegate yet.
The function that receives your callable may do whatever it wants with it. A common example is in your question, a web service callback. First you tell the framework what should be done in case a request is received (by defining actions in a function and making that function available for the framework), and in your example enter a loop with listenHTTP which calls your code when it receives a request. If you want to read more on this topic: https://en.wikipedia.org/wiki/Event_(computing)#Event_handler
Delegates are function pointers with context information attached. Say you want to add handlers that act on other elements available in the current context. Like a button that turns an indicator red. Example:
class BuildGui {
Indicator indicator;
Button button;
this(){
... init
button.clickHandler({ // curly braces: implicit delegate in this case
indicator.color = "red"; // notice access of BuildGui member
});
button.clickHandler(&otherClickHandler); // methods of instances can be delegates too
}
void otherClickHandler(){
writeln("other click handler");
}
}
In this imaginary Button class all click handlers are saved to a list and called when it is clicked.
There were several questions in the OP. I am going to try to answer the following two:
Q: Could you show examples of D callbacks and explain where they can be helpful?
A: They are commonly used in all languages that support delegates (C# for an example) as event handlers. - You give a delegate to be called whenever an event is triggered. Languages that do not support delegates use either classes, or callback functions for this purpose. Example how to use callbacks in C++ using the FLTK 2.0 library: http://www.fltk.org/doc-2.0/html/group__example2.html. Delegates are perfect for this as they can directly access the context. When you use callbacks for this purpose you have to pass along all the objects you want to modify in the callback... Check the mentioned FLTK link as an example - there we have to pass a pointer to the fltk::Window object to the window_callback function in order to manipulate it. (The reason why FLTK does this is that back FLTK was born C++ did not have lambdas, otherwise they would use them instead of callbacks)
Example D use: http://dlang.org/phobos/std_signals.html
Q: Why I can't simply pass one function to another and need to wrap it to Delegate?
A: You do not have to wrap to delegates - it depends what you want to accomplish... Sometimes passing callbacks will just work for you. You can't access context in which you may want to call the callback, but delegates can. You can, however pass the context along (and that is what some C/C++ libraries do).
I think what you are asking is explained in the D language reference
Quote 1:
A function pointer can point to a static nested function
Quote 2:
A delegate can be set to a non-static nested function
Take a look at the last example in that section and notice how a delegate can be a method:
struct Foo
{
int a = 7;
int bar() { return a; }
}
int foo(int delegate() dg)
{
return dg() + 1;
}
void test()
{
int x = 27;
int abc() { return x; }
Foo f;
int i;
i = foo(&abc); // i is set to 28
i = foo(&f.bar); // i is set to 8
}
There are already excellent answers. I just want to try to make simple summary.
Simply: delegate allows you to use methods as callbacks.
In C, you do the same by explicitly passing the object (many times named context) as void* and cast it to (hopefully) right type:
void callback(void *context, ...) {
/* Do operations with context, which is usually a struct */
doSomething((struct DATA*)context, ...);
doSomethingElse((struct DATA*)context, ...);
}
In C++, you do the same when wanting to use method as callback. You make a function taking the object pointer explicitly as void*, cast it to (hopefully) right type, and call method:
void callback(void* object, ...) {
((MyObject*)object)->method(...);
}
Delegate makes this all implicitly.
I am using FluentMongo and the MongoDBCSharpDriver. My code was working fine for a while, but after updating my MongoCSharpDriver, I now I keep getting this error when I try to query the database:
"Discriminators can only be registered for classes, not for interface MyLib.Services.IRepoData."
The interface IRepoData is just one that I use for all my objects saved to MongoDB. It just defines _id for everything. Here is the line that is breaking:
var item = Collection.AsQueryable().SingleOrDefault(a => a.Id == itemID);
Can anyone shed some light on this one? If I just use .SingleOrDefault() with no lambda then it works fine, its passing a lambda that breaks it.
EDIT
In case this helps...
var Collection = GetCollection<MyClass>();
private MongoCollection<T> GetCollection<T>() where T : class, new()
{
string typeName = typeof(T).Name;
var collection = db.GetCollection<T>(typeName, safeMode);
return collection;
}
Found it! I was calling GetCollection() from within another generic method, like this:
public T Save<T>(T item) where T : class, IRepoData, new()
{
GetCollection<T>().Save(item);
}
This caused GetCollection to see T as the interface instead of the actual instance class. GetCollection works fine anywhere else.
For anyone else with this problem, I just used a low level query like this instead... Collection.FindOneAs<T>(Query.EQ("Id", itemID.ToString()));
I could use some really good links that explain Generics and how to use them. But I also have a very specific question, relater to working on a current project.
Given this class constructor:
public class SecuredDomainViewModel<TDomainContext, TEntity> : DomainViewModel<TDomainContext, TEntity>
where TDomainContext : DomainContext, new()
where TEntity : Entity, new()
public SecuredDomainViewModel(TDomainContext domainContext, ProtectedItem protectedItem)
: base(domainContext)
{
this.protectedItem = protectedItem;
}
And its creation this way:
DomainViewModel d;
d = new SecuredDomainViewModel<MyContext, MyEntityType>(this.context, selectedProtectedItem);
Assuming I have 20 different EntityTypes within MyContext, is there any easier way to call the constructor without a large switch statement?
Also, since d is DomainViewModel and I later need to access methods from SecuredDomainViewModel, it seems I need to do this:
if (((SecuredDomainViewModel<MyContext, MyEntityType>)d).CanEditEntity)
But again "MyEntityType" could actually be one of 20 diffent types. Is there anyway to write these types of statements where MyEntityType is returned from some sort of Reflection?
Additional Info for Clarification:
I will investigate ConstructorInfo, but I think I may have incorrectly described what I'm looking to do.
Assume I have the DomainViewModel, d in my original posting.
This may have been constructed via three possible ways:
d = new SecuredDomainViewModel<MyContext, Order>(this.context, selectedProtectedItem);
d = new SecuredDomainViewModel<MyContext, Invoice>(this.context, selectedProtectedItem);
d = new SecuredDomainViewModel<MyContext, Consumer>(this.context, selectedProtectedItem);
Later, I need to access methods on the SecuredDomainViewModel, which currently must be called this way:
ex: if (((SecuredDomainViewModel<MyContext, Order)d).CanEditEntity)
ex: if (((SecuredDomainViewModel<MyContext, Invoice)d).CanEditEntity)
ex: if (((SecuredDomainViewModel<MyContext, Consumer)d).CanEditEntity)
Assuming I have N+ entity types in this context, what I was hoping to be able to do is
something like this with one call:
ex: if (((SecuredDomainViewModel<MyContext, CurrentEntityType)d).CanEditEntity)
Where CurrentEntityType was some sort of function or other type of call that returned Order, Invoice or Consumer based on the current item entity type.
Is that possible?
You can create a non-generic interface that has the CanEditEntity property on it, make SecuredDomainViewModel inherit off that, then call the property through the interface...
Also, the new() constructor allows you to call a constructor on a generic type that has no arguments (so you can just write new TEntity()), but if you want to call a constructor that has parameters one handy trick I use is to pass it in as a delegate:
public void Method<T>(Func<string, bool, T> ctor) {
// ...
T newobj = ctor("foo", true);
// ...
}
//called later...
Method((s, b) => new MyClass(s, b));
I can't help on the links, and likely not on the type either.
Constructor
If you have the Type, you can get the constructor:
ConstructorInfo construtor = typeof(MyEntityType).GetConstructor(new object[]{TDomainContext, ProtectedItem});
Type
I'm not really sure what you're looking for, but I can only see something like
if (((SecuredDomainViewModel<MyContext, entityType>)d).CanEditEntity)
{
entityType=typeof(Orders)
}
being what you want.