Re: Rvalue references
On Sunday, 14 January 2018 at 00:55:27 UTC, Jonathan M Davis wrote: [...] It the simplest case, it means that the compiler does a bitwise copy rather than a deep copy, but in other cases, it means that the compiler is able to use the object in-place rather than creating a deep copy that it places elsewhere. If you want to know more on the topic, you can always look into C++ move constructors. They were added so that C++ could avoid a lot of unnecessary copies. D took the approach of requiring that structs be moveable (e.g. it's undefined behavior to have a struct contain a pointer to itself), which simplifies things considerably. [...] Thanks!
Re: Where can get the Number Convert module?Thanks.
On Sunday, January 14, 2018 03:28:28 FrankLike via Digitalmars-d-learn wrote: > On Sunday, 14 January 2018 at 03:09:40 UTC, Jonathan M Davis > > wrote: > > On Sunday, January 14, 2018 02:41:39 FrankLike via > > > > Digitalmars-d-learn wrote: > >> [...] > > > > I'd suggest looking at > > > > [...] > > I get the result "1000" from byte[] byteData =[0,0,0,8]; > > Thank you very much. Good to hear. On a side note, I would point out that you almost certainly want to be using ubyte and not byte. byte is signed, whereas ubyte is unsigned. So, if you want to represent bytes of memory rather than an integral value between 1 and 127, then you want ubyte. - Jonathan M Davis
Re: Where can get the Number Convert module?Thanks.
On Sunday, 14 January 2018 at 03:28:28 UTC, FrankLike wrote: On Sunday, 14 January 2018 at 03:09:40 UTC, Jonathan M Davis wrote: On Sunday, January 14, 2018 02:41:39 FrankLike via Digitalmars-d-learn wrote: [...] I'd suggest looking at [...] I get the result "1000" from ubyte[] byteData =[0,0,0,8]; Thank you very much.
Re: Where can get the Number Convert module?Thanks.
On Sunday, 14 January 2018 at 03:09:40 UTC, Jonathan M Davis wrote: On Sunday, January 14, 2018 02:41:39 FrankLike via Digitalmars-d-learn wrote: [...] I'd suggest looking at [...] I get the result "1000" from byte[] byteData =[0,0,0,8]; Thank you very much.
Re: Where can get the Number Convert module?Thanks.
On Sunday, January 14, 2018 02:41:39 FrankLike via Digitalmars-d-learn wrote: > On Sunday, 14 January 2018 at 02:03:39 UTC, Jonathan M Davis > > wrote: > > Well, I'm not quite sure what you mean, but if you mean that > > Such as byte[] byteData =[0,0,0,8]; > to convert, at last,get the string bit :"100".or get the BitArray. I'd suggest looking at https://dlang.org/phobos/std_bitmanip.html#bitsSet and https://dlang.org/phobos/std_bitmanip.html#BitArray I'm not sure that either of them does quite what you want, but you may be able to use them to get what you want. Alternatively, you can convert to and from string using a radix with std.conv.to - e.g. assert(to!string(42, 2) == "101010"); assert(to!int("101010", 2) == 42); You have to already have convered the array of ubytes to an integral value to do that, but you can get the base-2 representation of a number that way. And one of these could be used to convert the array of ubytes to an integral: https://dlang.org/phobos/std_bitmanip.html#bigEndianToNative https://dlang.org/phobos/std_bitmanip.html#littleEndianToNative https://dlang.org/phobos/std_bitmanip.html#peek https://dlang.org/phobos/std_bitmanip.html#read The only ways in Phobos that I'm aware of to get a number in binary format as a string would be to use std.conv.to or std.conv.parse with a radix or to use toString on BitArray. So, if that's your ultimate goal, you'll need to figure out how to use one of those to get there. - Jonathan M Davis
Re: Where can get the Number Convert module?Thanks.
On Sunday, 14 January 2018 at 02:41:39 UTC, FrankLike wrote: On Sunday, 14 January 2018 at 02:03:39 UTC, Jonathan M Davis wrote: Well, I'm not quite sure what you mean, but if you mean that Sorry,Such as byte[] byteData =[8,0,0,0]; to convert, at last,get the string bit :"100".or get the BitArray. Thanks.
Re: Where can get the Number Convert module?Thanks.
On Sunday, 14 January 2018 at 02:03:39 UTC, Jonathan M Davis wrote: Well, I'm not quite sure what you mean, but if you mean that Such as byte[] byteData =[0,0,0,8]; to convert, at last,get the string bit :"100".or get the BitArray. Thanks.
Re: function template specialization question D vs. C++
On Saturday, January 13, 2018 19:32:06 Jonathan M Davis via Digitalmars-d- learn wrote: > On Sunday, January 14, 2018 02:24:52 Adam D. Ruppe via Digitalmars-d-learn > wrote: > > On Sunday, 14 January 2018 at 02:14:50 UTC, Jonathan M Davis > > > > wrote: > > > If you're using template constraints rather than template > > > specializations, then you can't have any unconstrained > > > templates. > > > > Not true: see the tip of the week here > > http://arsdnet.net/this-week-in-d/2016-sep-04.html > > Well, that's a neat trick to get around the restriction that I stated, but > it doesn't really make what I said untrue. Unless you're using template > specializations, you can't overload an unconstrained template. That tip > just shows a way to combine template specializations and template > constraints so that you get the same effect as if you were allowed to > overload > unconstrained templates with constrained templates without using template > specializations. It is a neat trick though. - Jonathan M Davis
Re: function template specialization question D vs. C++
On Sunday, 14 January 2018 at 00:09:42 UTC, kdevel wrote: The compiler does not allow me to specialize the primary function template for double: Yes, it does., and it works for float and double. Just `real` matches both equally, so that's the error for that type. Let me quote the spec: https://dlang.org/spec/template.html#parameters_specialization "The template picked to instantiate is the one that is most specialized that fits the types of the TemplateArgumentList. Determining which is more specialized is done in the same way as the C++ partial ordering rules. If the result is ambiguous, it is an error." So, if there's only T:float, float, double, and real can all be implicitly converted to that, so it is an exact match for float, but a half-match for double and real, which are still better than unspecialized T, so it matches that. When you have T:float and T:double, then double, being an exact match for the second one, triggers that. Similarly, float is still an exact match for the first one, so that's the best. But real is a half-match for both - it implicitly converts, but is not exactly either. So it is ambiguous - the compiler doesn't know which is a best fit. You can add T:real to exactly match that, or use a constraint to filter out real on one or both to remove it from consideration.
Re: function template specialization question D vs. C++
On Sunday, January 14, 2018 02:24:52 Adam D. Ruppe via Digitalmars-d-learn wrote: > On Sunday, 14 January 2018 at 02:14:50 UTC, Jonathan M Davis > > wrote: > > If you're using template constraints rather than template > > specializations, then you can't have any unconstrained > > templates. > > Not true: see the tip of the week here > http://arsdnet.net/this-week-in-d/2016-sep-04.html Well, that's a neat trick to get around the restriction that I stated, but it doesn't really make what I said untrue. Unless you're using template specializations, you can't overload an unconstrained template. That tip just shows a way to combine template specializations and template constraints so that you get the same effect as if you were allowed to overload unconstrained templates with constrained templates without using template specializations. - Jonathan M Davis
Re: function template specialization question D vs. C++
On Sunday, 14 January 2018 at 02:14:50 UTC, Jonathan M Davis wrote: If you're using template constraints rather than template specializations, then you can't have any unconstrained templates. Not true: see the tip of the week here http://arsdnet.net/this-week-in-d/2016-sep-04.html
Re: function template specialization question D vs. C++
On Sunday, January 14, 2018 01:02:46 kdevel via Digitalmars-d-learn wrote: > On Sunday, 14 January 2018 at 00:30:37 UTC, Nicholas Wilson wrote: > > The usual way to do what you are trying to do is with template > > constraints. > > > > void foo(T)() if (is(T== float)) { ...} > > Thanks. That works but looks a bit ugly. Am I right that I have > to leave out the primary (unconstrained) template? If you're using template constraints rather than template specializations, then you can't have any unconstrained templates. A given argument will have to compile with exactly one overload of the template - or none, if you don't want it to compile with any of them. However, you can also specialize internally via static if, which may or may not be better, depending on what you're trying to do. e.g. void foo(T)(T arg) { static if(is(T == int)) { // do something } else static if(is(T == float)) { // do something else } else { // do something with the rest... } } To do the same thing with overloaded templates, you'd need to do void foo(T)(T arg) if(is(T == int)) { // do something } void foo(T)(T arg) if(is(T == float)) { // do something else } void foo(T)(T arg) if(!is(T == int) && !is(T == float)) { // do something with the rest... } In general, at this point, it's considered best practice to try and make the top-level constraints as general as possible and specialize internally rather than overloading at the top-level (unless the overloads really are disjoint - e.g. they take a different number of arguments). Doing all of the specializations at the top-level has made the documentation for some of the functions in Phobos harder to read through and made error messages worse, since you have to dig through a bunch of different template constraints, whereas by making the top-level constraints more general and trying to push the specializations inside with static ifs, things become more manageable. Also, if you want to T to be implicitly convertibly to the given type, then use : instead of ==, and if you don't care about the type modifiers such as const, then use std.traits.Unqual. e.g. void foo(T)(T arg) if(is(T == float)) { } will not compile if the argument is a const float, whereas void foo(T)(T arg) if(is(Unqual!T == float)) { } will. And in the case of the static if above, a const float would take the else branch. So, Unqual would probably be merited there as well. For better or worse, D templates tend to end up with a fair bit of metaprogramming used with constraints and static ifs. You're not going to see very many cases of templates without any constraints or specializations (and most folks don't use specializations). You get by far the best control using template constraints, and you can improve error messages by making it so that arguments that wouldn't compile with the template fail the constraint instead of generating an error from inside the template. - Jonathan M Davis
Re: Where can get the Number Convert module?Thanks.
On Sunday, January 14, 2018 01:45:37 FrankLike via Digitalmars-d-learn wrote: > Hi,everyone, > I need some help on 'Number Convert module' in D,such as > byte[] type to BinaryDigit. > Where can get the module? > > Thanks. Well, I'm not quite sure what you mean, but if you mean that you want to take a ubyte[] and do something like take arr[0 .. 4] and convert that to int, then you should check out https://dlang.org/phobos/std_bitmanip.html In particular, https://dlang.org/phobos/std_bitmanip.html#bigEndianToNative https://dlang.org/phobos/std_bitmanip.html#peek https://dlang.org/phobos/std_bitmanip.html#read - Jonathan M Davis
Where can get the Number Convert module?Thanks.
Hi,everyone, I need some help on 'Number Convert module' in D,such as byte[] type to BinaryDigit. Where can get the module? Thanks.
Range over a container r-value with disabled postblit
Given my combined hashmap and hashset container `HashMapOrSet` defined at https://github.com/nordlow/phobos-next/blob/master/src/hashmap_or_hashset.d with deterministic memory management and disabled copy constructions and a member byElement() defined as @property auto byElement()() inout { dln("entering byElement"); alias This = ConstThis; // TODO is the use of `&this` incorrect when `this` is an r-value? auto result = ByElement!This((ElementRef!This(cast(This*)&this))); result.initFirstNonEmptyBin(); dln("leaving byElement"); return result; } scope auto opSlice()() inout return { return byElement(); } where static private struct ByElement(HashMapOrSetType) { static if (is(ElementType == class)) { /// Get reference to front element (key and value). @property scope auto front()() return @trusted { /* cast away const from `HashMapOrSetType` for classes * because class elements are currently hashed and compared * compared using their identity (pointer value) `is` */ return cast(ElementType)table.binElementsAt(binIx)[elementOffset]; } } else { /// Get reference to front element (key and value). @property scope auto front()() { return table.binElementsAt(binIx)[elementOffset]; } } public ElementRef!HashMapOrSetType _elementRef; alias _elementRef this; } iteration via opSlice works fine when `X` is fed as `this` to `byElement` as an l-value as in import digestx.fnv : FNV; alias X = HashMapOrSet!(uint, void, null, FNV!(64, true)); const x = X.withElements([11].s); foreach (e; x.byElement) {} but when `X` is fed as an r-value `this` to `byElement` as in import digestx.fnv : FNV; alias X = HashMapOrSet!(uint, void, null, FNV!(64, true)); foreach (e; X.withElements([11].s).byElement) {} I get a behaviour that seems to indicate that the instance of `X` is freed after `byValue()` (opSlice) returns but before the `ByValue`-range is consumed, resulting in incorrect (undefind) behaviour. Is it incorrect to use `&this` as follows auto result = ByElement!This((ElementRef!This(cast(This*)&this))); in the `byElement`? If so, is there a way around this problem except for making my container be RC-allocated? My current proposal for a solution is to make `byElement` a free unary function byElement(auto ref X x) which statically checks via static if (__traits(isRef, x)) whether the `X`-instance is passed as either an - l-value, where my current solution works (ByLvalueElement), or - r-value, in which the X-instance instead is moved into range (ByRvalueElement). byValue can be used via UFCS, but this solution removes the possibility for using the opSlice-overload which I can live with. Further, does all EMSI-container-style containers (with disabled postblit) have the same issue with ranges over r-value instances of its containers?
Re: function template specialization question D vs. C++
On Sunday, 14 January 2018 at 00:30:37 UTC, Nicholas Wilson wrote: The usual way to do what you are trying to do is with template constraints. void foo(T)() if (is(T== float)) { ...} Thanks. That works but looks a bit ugly. Am I right that I have to leave out the primary (unconstrained) template?
Re: Rvalue references
On Friday, January 12, 2018 01:59:49 Tony via Digitalmars-d-learn wrote: > On Monday, 8 January 2018 at 23:31:27 UTC, Jonathan M Davis wrote: > > auto foo(T)(auto ref T t) > > { > > > > return t; > > > > } > > > > foo(42); > > > > will result in foo being instantiated as > > > > int foo(int t) > > { > > > > return t; > > > > } > > > > whereas > > > > int i; > > foo(i); > > > > will result in foo being instantiated as > > > > int foo(ref int t) > > { > > > > return t; > > > > } > > > > So, by using auto ref, a function can accept both lvalues and > > rvalues. And in D, rvalues get moved, not copied. > > What does it mean to "move" a variable/value instead of copying > it? It the simplest case, it means that the compiler does a bitwise copy rather than a deep copy, but in other cases, it means that the compiler is able to use the object in-place rather than creating a deep copy that it places elsewhere. If you want to know more on the topic, you can always look into C++ move constructors. They were added so that C++ could avoid a lot of unnecessary copies. D took the approach of requiring that structs be moveable (e.g. it's undefined behavior to have a struct contain a pointer to itself), which simplifies things considerably. You can also check out the stackoverflow questions that I linked to before: https://stackoverflow.com/questions/35120474/does-d-have-a-move-constructor https://stackoverflow.com/questions/6884996/questions-about-postblit-and-move-semantics They don't anwser what a move is, but they do give more context. > Was "auto ref" created for anything besides structs? auto ref works with any type whatsoever, but as far as efficiency goes, it's kind of pointless for other types, because most everything else is at most 64 bits, which would be the size of a pointer on a 64-bit system. reals are larger, and if we ever get cent and ucent, those would be larger, but most stuff that isn't structs fits in 64 bits, meaning that copying them is not expensive. However, if you need to forward the refness of an argument, then auto ref can still be critical - e.g. std.conv.emplace constructs an object in memory, and if it couldn't pass the refness of the arguments on to the constructor that it calls, then constructors with ref parameters wouldn't work properly. Similarly, in templated code, you can have stuff like front on a range which may or may not return by ref, so by using auto ref on the return type of front when wrapping one range with another, the refness of the underlying range's front can be passed along. Arguably, this aspect of auto ref matters _way_ more than trying to make it more efficient to copy structs. - Jonathan M Davis
Re: function template specialization question D vs. C++
On Sunday, 14 January 2018 at 00:09:42 UTC, kdevel wrote: fusp.d ``` import std.stdio; import std.typecons; void foo (T) () { writeln ("(1) foo T = ", T.stringof); } void foo (T : float) () { writeln ("(2) foo T = ", T.stringof); } // void foo (T : double) () // { //writeln ("(2) foo T = ", T.stringof); // } void main () { foo!float; foo!double; foo!real; foo!string; } ``` prints (2) foo T = float (2) foo T = double (2) foo T = real (1) foo T = string I would have expected (2) foo T = float (1) foo T = double (1) foo T = real (1) foo T = string The compiler does not allow me to specialize the primary function template for double: The `:` is not a type equality check. It is more like a "converts to" or "is of the form of". i.e. `void foo (T : float) ()` reads as "foo is a template function returning void, taking one template type T that converts to float, and no runtime args." The usual way to do what you are trying to do is with template constraints. void foo(T)() if (is(T== float)) { ...}
function template specialization question D vs. C++
fusp.d ``` import std.stdio; import std.typecons; void foo (T) () { writeln ("(1) foo T = ", T.stringof); } void foo (T : float) () { writeln ("(2) foo T = ", T.stringof); } // void foo (T : double) () // { //writeln ("(2) foo T = ", T.stringof); // } void main () { foo!float; foo!double; foo!real; foo!string; } ``` prints (2) foo T = float (2) foo T = double (2) foo T = real (1) foo T = string I would have expected (2) foo T = float (1) foo T = double (1) foo T = real (1) foo T = string The compiler does not allow me to specialize the primary function template for double: $ dmd fusp.d fusp.d(23): Error: fusp.foo called with argument types () matches both: fusp.d(9): fusp.foo!real.foo() and: fusp.d(14): fusp.foo!real.foo() fusp.d(23): Error: foo!real has no effect Is this a compiler error? C++ function template specialization works as expected: fusp.cc ``` #include template void foo () { std::cout << "(1) " << __PRETTY_FUNCTION__ << "\n"; } template<> void foo () { std::cout << "(2) " << __PRETTY_FUNCTION__ << "\n"; } template<> void foo () { std::cout << "(3) " << __PRETTY_FUNCTION__ << "\n"; } int main () { foo (); foo (); foo (); foo (); foo (); } ``` $ g++ fusc.cc $ ./a.out (1) void foo() [with T = int] (2) void foo() [with T = float] (3) void foo() [with T = double] (1) void foo() [with T = long double] (1) void foo() [with T = std::__cxx11::basic_string]
Re: compile-time checked format strings
On Saturday, 13 January 2018 at 19:40:09 UTC, Adam D. Ruppe wrote: For ints, it catches all that, but for float, it just bails out of the check as soon as it actually *succeeds* - because that kills CTFE. Confirmed. Thanks! args.d ``` import std.stdio; void main () { // writefln!"%2.2d %2.2d" (1); // OK: Orphan format specifier //writefln!"%2.2d" (1, 2); // OK: Orphan format arguments: } ```
Re: compile-time checked format strings
On Saturday, 13 January 2018 at 19:40:09 UTC, Adam D. Ruppe wrote: On Saturday, 13 January 2018 at 19:15:49 UTC, kdevel wrote: dmd checks the types but does not count the arguments. so note that dmd doesn't actually do any checks here - it is all done in library code. The implementation is amusingly simple: https://github.com/dlang/phobos/blob/master/std/format.d#L5803 Yeah there's already an interesting issue about this https://issues.dlang.org/show_bug.cgi?id=17381
Re: compile-time checked format strings
On Saturday, 13 January 2018 at 19:15:49 UTC, kdevel wrote: dmd checks the types but does not count the arguments. so note that dmd doesn't actually do any checks here - it is all done in library code. The implementation is amusingly simple: https://github.com/dlang/phobos/blob/master/std/format.d#L5803 try format(...) catch(Exception) trigger compile time error. But, since float format doesn't work at compile time, this method doesn't actually work to catch any float-related problems except mismatching format characters! For ints, it catches all that, but for float, it just bails out of the check as soon as it actually *succeeds* - because that kills CTFE. We should just put in a fake stub float printer to hack this past for checking purposes.
compile-time checked format strings
occasion: http://forum.dlang.org/thread/mutegviphsjwqzqfo...@forum.dlang.org?page=3#post-mailman.2136.1515709204.9493.digitalmars-d-announce:40puremagic.com dmd checks the types but does not count the arguments. ctcfs.d ``` import std.stdio; import std.math; void unit (T) () { auto pi = 4 * atan (T (1)); writefln!"%30.24f" (pi, pi); // no error! writefln!"%30.24f %30.24f" (pi, pi); // OK // writefln!"%30.24d %30.24f" (pi, pi); // OK: "incompatible format character writefln!"%30.24f %30.24f %30.24f" (pi, pi); // no error } void main () { unit!float; } ``` $ dmd ctcfs.d $ ./ctcfs 3.141592741012573242187500 3.141592741012573242187500 3.141592741012573242187500 3.141592741012573242187500 3.141592741012573242187500 std.format.FormatException@/.../dmd2/linux/bin64/../../src/phobos/std/format.d(479): Orphan format specifier: %f /.../dmd2/linux/bin64/../../src/phobos/std/exception.d:615 pure @safe bool std.exception.enforceEx!(std.format.FormatException).enforceEx!(bool).enforceEx(bool, lazy immutable(char)[], immutable(char)[], ulong) [0x44503c] /.../dmd2/linux/bin64/../../src/phobos/std/format.d:479 @safe uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, float, float).formattedWrite(ref std.stdio.File.LockingTextWriter, const(char[]), float, float) [0x44c436] /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d:1496 @safe void std.stdio.File.writefln!(char, float, float).writefln(const(char[]), float, float) [0x44c340] /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d:3797 @safe void std.stdio.writefln!(char, float, float).writefln(const(char[]), float, float) [0x44c2b7] /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d:3791 @safe void std.stdio.writefln!("%30.24f %30.24f %30.24f", float, float).writefln(float, float) [0x44da27] ctcfs.d:10 @safe void ctcfs.unit!(float).unit() [0x443673] ctcfs.d:15 _Dmain [0x443614]
Re: Using Postgres connection functions
On Saturday, 13 January 2018 at 10:10:41 UTC, Jacob Carlborg wrote: There's a native D library, ddb [1], for connecting to Postgres. Then you don't have to worry about null-terminated strings. There are several D libraries that I would consider "native": derelict-pq, dpq, dpq2 and ddb. The latter perhaps has the distinction that it doesn't use libpq, but rather implements the Postgres FE/BE protocol. That's a bit *too* native for my taste. It means the library maintainer has to keep up with changes to the internal protocol, which although published, the Postgres group doesn't have to maintain compatibility from version to version. For example, they haven't dropped the PQsetdbLogin function even though the PQconnectdb and PQconnectdbParams functions are obviously preferred. OTOH, there used to be an AsciiRow message format in the protocol, that was dropped, unceremoniously (not even mentioned in the release notes).
Re: Asio Bindings?
I'm a little late (1.5 years) to the ASIO discussion party, but I recently wrote something for myself that may be useful to others: https://github.com/dewf/DASIOClient I haven't published to DUB yet because 1) it's a pretty naive implementation and 2) I'm still very new to D, and 3) there's a built-in logging thing that will probably annoy everybody (which is why I need to spend more time with D, so I can learn The Right Way) It's "batteries included" (DLL+LIB files for Win32/64), so you don't have to compile the C library yourself. Note: it currently only really supports the ASIOSTInt32LSB sample type, because that's what all my test hardware uses; I have no idea if the other sample types are in common use with modern audio interfaces. But the C library also passes through ASIOSTFloat32LSB/ASIOSTFloat64LSB, so it would be very easy to modify the D wrapper to accommodate those, as well. If the included example program plays silence, then you'll probably need a new sample type :)
Re: Is Nullable supposed to provide Optional semantics?
On Saturday, 30 December 2017 at 19:11:05 UTC, Steven Schveighoffer wrote: Please file a bug report. Sorry for the delay - stuff happened. I reopened an existing bug that I found: https://issues.dlang.org/show_bug.cgi?id=17440
Re: Using Postgres connection functions
On 2018-01-13 05:17, Joe wrote: I'm trying to learn how to use D to connect (and send queries) to Postgres, i.e., libpq in C. So my question is: is there an easier or better way of passing two arrays of C null-terminated strings to an extern(C) function? There's a native D library, ddb [1], for connecting to Postgres. Then you don't have to worry about null-terminated strings. [1] http://code.dlang.org/packages/ddb -- /Jacob Carlborg