Re: RAII pointers
On Monday, 29 May 2017 at 23:39:17 UTC, Russel Winder wrote: C++ allows one to create types that are pointer types but wrap a primitive pointer to give RAII handling of resources. For example: class Dvb::FrontendParameters_Ptr { private: dvb_v5_fe_parms * ptr; public: FrontendParameters_Ptr(FrontendId const & fei, unsigned int const verbose = 0, unsigned int const legacy = 0); FrontendParameters_Ptr(FrontendParameters_Ptr const &) = delete; FrontendParameters_Ptr & operator=(FrontendParameters_Ptr const &) = delete; ~FrontendParameters_Ptr() {dvb_fe_close(ptr); } dvb_v5_fe_parms * c_ptr() const { return ptr; } dvb_v5_fe_parms * operator->() const { return ptr; } }; Has anyone any experience of doing the analogous thing idiomatically in D. I just re-realised I manually constructed a C++ abstraction layer around some of libdvbv5, so I am going to do the same for D. However whilst I (sort of) understand doing the wrapping with C++, I am not sure I have seen anyone wrapping C pointers with RAII in D. I've found this pattern works rather well: module frontendparametersptr; struct FrontendParametersPtr { // No constructors, initialization with parameters // is done via the frontendParametersPtr function @disable this(this); ~this() { // null check is often useful to detect e.g. // if this object has been `move`d if (_ptr) dvb_fe_close(_ptr); } // with DIP1000, could also return `scope` inout(dvb_v5_fe_parms)* ptr() inout { return _ptr; } alias ptr this; package: void construct(/*your args here*/) { /*...*/ } private: dvb_v5_fe_parms* _ptr; } /// Replaces constructor, i.e. can be called with no arguments for /// replacing "default" construction of C++ auto frontendParametersPtr(Args...)(auto ref Args args) { import std.functional : forward; FrontendParametersPtr result = void; result.construct(forward!args); return result; // moves result, no copy is made } ///- module app; import frontendparametersptr; void main() { auto ptr = frontendParametersPtr(/* your args here */); } The main idea is that construction is handled by the `construct` function (which could be overloaded), instead of `this(...)` constructors: this way client code would either get default-initialized (.init) pointers, or those constructed with appropriate arguments (even with no arguments, if such is needed). Disabling copying is obvious. The rest depends on taste and purpose.
Re: RAII pointers
On Monday, 29 May 2017 at 23:39:17 UTC, Russel Winder wrote: C++ allows one to create types that are pointer types but wrap a primitive pointer to give RAII handling of resources. For example: class Dvb::FrontendParameters_Ptr { private: dvb_v5_fe_parms * ptr; public: FrontendParameters_Ptr(FrontendId const & fei, unsigned int const verbose = 0, unsigned int const legacy = 0); FrontendParameters_Ptr(FrontendParameters_Ptr const &) = delete; FrontendParameters_Ptr & operator=(FrontendParameters_Ptr const &) = delete; ~FrontendParameters_Ptr() {dvb_fe_close(ptr); } dvb_v5_fe_parms * c_ptr() const { return ptr; } dvb_v5_fe_parms * operator->() const { return ptr; } }; Has anyone any experience of doing the analogous thing idiomatically in D. Yes, I generally use structs with `@disable this(this)` and std.algorithm.mutation.move for this. Something like (untested, but general approach): --- module dvb; struct FrontendParameters_Ptr { private: dvb_v5_fe_parms* ptr; public: @disable this(this); this(ref const FrontendId fei, const uint verbose = 0, const uint legacy = 0) { ... } ~this() { dvb_fe_close(ptr); } auto c_ptr() const { return ptr; } alias c_ptr this; } --- Be aware that the above deliberately prohibits normal struct copy construction, so there is always only a single struct object. "Borrow" it via ref / ref const or std.algorithm.mutation.move it to change the owner. Or wrap this struct itself in a lifetime management struct (such as std.typecons.RefCounted) if you need multiple owners.
Re: RAII pointers
On Monday, 29 May 2017 at 23:39:17 UTC, Russel Winder wrote: C++ allows one to create types that are pointer types but wrap a primitive pointer to give RAII handling of resources. For example: [...] std.stdio.File does basically the same thing with C's FILE*
RAII pointers
C++ allows one to create types that are pointer types but wrap a primitive pointer to give RAII handling of resources. For example: class Dvb::FrontendParameters_Ptr { private: dvb_v5_fe_parms * ptr; public: FrontendParameters_Ptr(FrontendId const & fei, unsigned int const verbose = 0, unsigned int const legacy = 0); FrontendParameters_Ptr(FrontendParameters_Ptr const &) = delete; FrontendParameters_Ptr & operator=(FrontendParameters_Ptr const &) = delete; ~FrontendParameters_Ptr() {dvb_fe_close(ptr); } dvb_v5_fe_parms * c_ptr() const { return ptr; } dvb_v5_fe_parms * operator->() const { return ptr; } }; Has anyone any experience of doing the analogous thing idiomatically in D. I just re-realised I manually constructed a C++ abstraction layer around some of libdvbv5, so I am going to do the same for D. However whilst I (sort of) understand doing the wrapping with C++, I am not sure I have seen anyone wrapping C pointers with RAII in D. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Best way for handle missing args in REST interface in vibed
@rootPathFromName interface API { @path("mytrack") @method(HTTPMethod.GET)Json doTrackSpeedAnalyze(int trackid, string startDateTime, string endDateTime); } class MyRouter : API { Config config; Database database; this(Config config, Database database) { this.config = config; this.database = database; } @path("/") void foo(string _error = null) // I expect that this will be called if exception happen in doTrackSpeedAnalyze { writeln("Error in console"); // does not writing on console } override: @errorDisplay!foo Json doTrackSpeedAnalyze(int trackid, string startDateTime, string endDateTime) // /api/mytrack?trackid=123=2000=2010 { if(endDateTime == "0") { throw new Exception("Some fields are empty"); } return Json.emptyObject; } } What I am doing wrong? Should I do override for foo? Should foo present in `interface`?
Re: purity question
On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote: Brad Roberts wrote: libraries that themselves aren't marked pure, there's a real need for escape hatches. A simple example: anything that has a malloc/free pair. they aren't pure. it is a sad misconception about purity, which D makes even more complex by allowing to mark, for example, *setters* as pure. but still, `malloc()` and `free()` aren't pure. and while various functions in std.math, for example, are marked `pure`, they aren't too. There is pureMalloc since 2.074.0 (it was never announced): https://github.com/dlang/druntime/pull/1746 However, without a pureFree it's rather limited in usefulness and needs to be workaround in real life: https://github.com/dlang/druntime/pull/1718
Re: Best way for handle missing args in REST interface in vibed
I wrote next code: void foo(string _error = null) { writeln("Error"); } override: @errorDisplay!foo Json doTrackSpeedAnalyze(int trackid, string startDateTime, string endDateTime) // /api/mytrack?trackid=123=2000=2010 { if(endDateTime.length == 0) { throw new Exception("End Date must not be empty"); } return Json.emptyObject; } If I access to url: /api/mytrack?trackid=123=2000 (witout endDateTime) I am expecting execution foo() block, but it does not happens. Why? And what do Exception here? Why should handle it?
Re: Best way for handle missing args in REST interface in vibed
On Monday, 29 May 2017 at 12:23:59 UTC, Suliman wrote: I am doing REST interface with vibed. And thinking about handling errors, if users forgot to pass all expected args in function. For example: foo(int x, int y) // get request { } /api/foo?x=111 And if user is forgot to pass `y` we will get error in the browser. What is the right way to handle curch cases? Wrap is with try-catch looks wrong. That depends on wether or not there is a sensible default for y, if so foo(int x, int y=0) ought to work.
Re: Best way for handle missing args in REST interface in vibed
On Monday, 29 May 2017 at 12:23:59 UTC, Suliman wrote: I am doing REST interface with vibed. And thinking about handling errors, if users forgot to pass all expected args in function. For example: foo(int x, int y) // get request { } /api/foo?x=111 And if user is forgot to pass `y` we will get error in the browser. What is the right way to handle curch cases? Wrap is with try-catch looks wrong. It's seems I found how to do it http://vibed.org/api/vibe.web.web/errorDisplay
Best way for handle missing args in REST interface in vibed
I am doing REST interface with vibed. And thinking about handling errors, if users forgot to pass all expected args in function. For example: foo(int x, int y) // get request { } /api/foo?x=111 And if user is forgot to pass `y` we will get error in the browser. What is the right way to handle curch cases? Wrap is with try-catch looks wrong.
Re: purity question
On Monday, 29 May 2017 at 11:25:06 UTC, ketmar wrote: almost all of them, 'cause they depends on FPU rounding settings. Well, yeah. IIRC contemporary floating point machine language instructions allow embedding of rounding mode into the instruction. A pity languages are lagging behind, stuck in the 1980s... WebAssembly is locking it to the default IEEE754-2008 round-to-even. Which is reasonable as they aim for max portability, albeit a bit limiting.
Re: purity question
Ola Fosheim Grøstad wrote: On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote: pure. and while various functions in std.math, for example, are marked `pure`, they aren't too. Out of curiosity, which functions in std.math aren't "pure" in the D sense? almost all of them, 'cause they depends on FPU rounding settings.
Re: purity question
On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote: pure. and while various functions in std.math, for example, are marked `pure`, they aren't too. Out of curiosity, which functions in std.math aren't "pure" in the D sense?
Re: purity question
Brad Roberts wrote: libraries that themselves aren't marked pure, there's a real need for escape hatches. A simple example: anything that has a malloc/free pair. they aren't pure. it is a sad misconception about purity, which D makes even more complex by allowing to mark, for example, *setters* as pure. but still, `malloc()` and `free()` aren't pure. and while various functions in std.math, for example, are marked `pure`, they aren't too.
Re: binding to C++
27.05.2017 02:44, Nicholas Wilson пишет: Thats weird. DMD may have got the mangling wrong. Could you post the exact mangling (i.e. non-demangled)? And if DMD has got it wrong and its just the one function you could just `pragma(mangle, ...);` it. I use pragma(mangle, "...") (how I forget about it?) and it works now, so probable DMD have got the mangling wrong. Trying to reduce case, but code isn't trivial nether D nor C++ side...