Attempt at creating a simpler unique_ptr
I'm sure something like this has been posted quite a bit, but I thought I'd try this for the heck of it. Looking at unique_ptr.h, oof, that ugly. So this is what I have so far. This to note - since templates can't except function arguments, I thought I'd make use of alias arguments and AliasSeq - since optional named arguments aren't a thing, I really have two options 1. Have Func be null on initialization by, unless something is passed 2. Make the template variadic The second of these two might actually be better. - This is really basic and it's just the sole template at the moment. /// Attempt to replicate C++'s unique_ptr, but a lot simpler. /// Hopefully Better C compatiable as well. import core.memory : __delete; import std.stdio : writeln; import std.typecons; import std.traits; import std.meta : AliasSeq; /// This allows us to pass a function as an argument /// for our pointer templates, and allows us to test /// if a function (one that deletes, which we'll have to /// figure a way to test for that later on) is passed to /// our UniquePointer. static auto ref SmartArgs(alias Thing, alias Func)() { return Func(Thing); } /// The UniquePointer /// Will delete whatever it references whenever it goes /// out of scope. Pretty basic at the moment. struct UniquePointer(alias Thing, alias Func) { @disable this(); this(auto Thing, Func = null) { auto ptr = &Thing; auto func = Func.nullable; static assert(isVoid!ptr, "Cannot use something of an incomplete type"); static assert(ptr.sizeof > 0, "Cannot use something of an incomplete type."); } ~this() { static if (!isNull!func && isFunction!func) { AliasSeq!(SmartArgs!(func, ptr)); } else { writeln("No deletion function way provided, or what was provided wasn't a function."); scope (exit) __delete(ptr); } } } This is a probably really complicated way of going about how to learn to use templates, but I just thought it'd be fun.
Re: Operator overloading for size_t
On Thursday, 14 March 2019 at 18:25:17 UTC, H. S. Teoh wrote: On Thu, Mar 14, 2019 at 06:07:46PM +, Alec Stewart via Digitalmars-d-learn wrote: [...] bool opEquals(ref const Interval i) const { // probably would be a bit more than just this, but for this issue // let's just stick with this. return d_start.opEquals(other.d_start) && d_end.opEquals(other.d_end); } There's no need to call opEquals explicitly like that. All you need to do is to use <, ==, and > as you normally would: bool opEquals(ref const Interval i) const { return d_start == other.d_start) && d_end == d_end; } T Thanks. I somehow managed to overthink this... For < and >, would one do this? size_t opCmp(ref const Interval other) const { return d_start < other.d_start; } size_t opCmp(ref const Interval other) const { return d_end < other.d_end; } size_t opCmp(ref const Interval other) const { return d_start > other.d_start; } size_t opCmp(ref const Interval other) const { return d_end > other.d_end; } Or would it better to do size_t opCmp(ref const Interval other) const { if (d_start < other.d_start) { return d_start < other.d_start; } else if (d_start > other.d_start) { return d_start > other.d_start; } else if (d_end < other.d_end) { return d_end < other.d_end; } else if (d_end > other.d_end) { return d_end > other.d_end; } else { return false; } }
Operator overloading for size_t
I thought (for shits and giggles) to try and implement the Aho-Corasick algorithm[1]. I thought I'd start with a struct to represent the "interval": struct Interval { size_t d_start; size_t d_end; size_t size; this(size_t start, size_t end) { d_start = start; d_end = end; size = d_end - d_start + 1; } } It'd be useful to check for equality and inequality between instances of `Interval`, so I thought to use `.opEquals` for `d_start` and `d_end`. bool opEquals(ref const Interval i) const { // probably would be a bit more than just this, but for this issue // let's just stick with this. return d_start.opEquals(other.d_start) && d_end.opEquals(other.d_end); } But I do get an error saying `none of the overloads of `opEquals` are callable using argument types `(const(ulong), const(ulong))`, candidates are:` and it doesn't say the candidates. So should I bother with operator overloading here, or just make a member function? [1] https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm
Re: Interfacing with C libs: weeding through C/C++ macros and such in header files
On Sunday, 13 January 2019 at 23:23:50 UTC, Alex wrote: These three are members of the standard library in D. https://dlang.org/phobos/core_memory.html Ah, yea that's way easier. At first, I would suggest to try out some automatic converters, which are written by the community: https://wiki.dlang.org/Bindings#Binding_generators especially dstep and dpp That would make it easier because there's a lot of preprocessor stuff that ends up being circular references if I use `enum` or `const`. Also, if there is a possibility to compile the C/C++ library, you could provide the interface only to the functions you need. Then, you reuse the existent code directly and interface the library by declaring the interfaces as extern in your D sources. https://dlang.org/spec/attribute.html#linkage That would also be easier. :P Thanks!
Interfacing with C libs: weeding through C/C++ macros and such in header files
Hello all! So while I have a decent grasp on D, I've been having trouble figuring out specific projects that I could do in D, so I thought I'd maybe find a little C or C++ library I could transfer over to D. I decided to make my life easier and look for something that's just a single header file, and while that does make things easier there are a TON of macros and inline functions that it almost seems ridiculous and it's somewhat overwhelming. Example without code; for some reason a macro is defined for the stdlib functions `malloc`, `realloc`, and `free`. Maybe it's just because I don't have any pro experience with C or C++, but that seems a bit excessive. Or I could just be dumb. Example with code (because I need help figuring out how whether I even need this or not): #ifndef RS_API #ifdef RS_NOINLINE /* GCC version 3.1 required for the no inline attribute. */ #if RS_GCC_VERSION > 30100 #define RS_API static __attribute__((noinline)) #elif defined(_MSC_VER) #define RS_API static __declspec(noinline) #else #define RS_API static #endif #elif RS_C99 #define RS_API static inline #elif defined(__GNUC__) #define RS_API static __inline__ #elif defined(_MSC_VER) #define RS_API static __forceinline #else #define RS_API static #endif #endif I understand what it's doing, but do I really any of this with D? And then there's this inline function #define RS_DATA_SIZE(f, s, input) \ do { \ if (rs_is_heap(input)) \ f(s, input->heap.buffer, rs_heap_len(input)); \ else\ f(s, input->stack.buffer, rs_stack_len(input)); \ } while (0) so yea. There's a little over 300 lines of preprocessor stuff. My question is how you all determine what to carry over from C libs in terms of preprocessor stuff. I imagine most useful values everyone just makes an enum for, and structs and unions are kept. Thanks for any help you give!