Tuesday, April 4, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 8 topics

bitrex <bitrex@de.lete.earthlink.net>: Apr 01 04:45AM -0400

Why does the following hack to have each instance of Bar inherit
from a unique "identifier" non-class type, based on the address of the
wrapper class Foo compile with -std=c++17, but not 14 or 11?
 
struct Foo
{
void type_id() {}
using type_id_t = void (Foo::*)();
 
struct BarBase
{
virtual ~BarBase();
};
 
template <void (Foo::*ID)()>
struct Bar : BarBase
{
 
};
 
static BarBase* make_base_ptr()
{
constexpr type_id_t id = &Foo::type_id;
return new Bar<id>;
}
};
Alvin <Alvin@invalid.invalid>: Apr 01 01:12PM +0200

On 2017-04-01 10:45, bitrex wrote:
> return new Bar<id>;
> }
> };
 
Explained in N4198:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html
 
C++17:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 30 02:58AM +0200

On 29-Mar-17 11:00 PM, Mr Flibble wrote:
> Linux uses UTF-8 for filenames
 
If so then Linux has diverged in an incompatible way from Unix mainstream.
 
Of old a Unix filename was just a sequence of bytes with no interpretation.
 
In particular, uppercasing or lowercasing a name was meaningless.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 30 03:02AM +0200

On 30-Mar-17 2:58 AM, Alf P. Steinbach wrote:
 
> If so then Linux has diverged in an incompatible way from Unix mainstream.
 
> Of old a Unix filename was just a sequence of bytes with no interpretation.
 
> In particular, uppercasing or lowercasing a name was meaningless.
 
And, sorry, I was half asleep, a Unix filename could be invalid as UTF-8.
 
 
Cheers!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Mar 30 10:06AM +0200

On 29/03/17 17:08, Scott Lurndal wrote:
>> can, of course, provide smaller divisions - but they are not "bytes" in
>> C parlance.
 
> Yes, the 48-bit systems have six 8-bit bytes.
 
Sorry - I misread your post as saying that 48-bit words were decomposed
into "6-bit bytes", not "6 bytes".
David Brown <david.brown@hesbynett.no>: Mar 30 10:05AM +0200

On 30/03/17 05:46, Daniel wrote:
> But others cannot, for example, none of the std::string find operations will
> work. I suppose you could specialize char_traits in basic_string with a
> unicode version, but that leads to other issues.
 
Why won't "find" work with UTF-8 strings? UTF-8 is self-synchronising -
if you search for one UTF-8 string inside another, matches done as
Unicode code points will be the same as matches done as raw 8-bit data.
David Brown <david.brown@hesbynett.no>: Mar 30 04:10PM +0200

On 30/03/17 14:30, Daniel wrote:
>> if you search for one UTF-8 string inside another, matches done as
>> Unicode code points will be the same as matches done as raw 8-bit data.dd
 
> Good point. I hadn't thought of that, thanks.
 
And I thought it was I who had missed something here.
 
The self-synchronising aspect of UTF-8 was a key design point, and I
think the ability to find substrings was a major reason for having it.
red floyd <dont.bother@its.invalid>: Mar 30 03:19PM -0700

On 3/30/2017 1:49 PM, Vir Campestris wrote:
 
> packed array of items of any (small) number of bits. Handy when you want
> to address a display with 8 greys per pixel. And yes, we did program
> that one in C!
 
The TI processor was the TMS340x0 series. I had the "pleasure" of
coding for the both the 34010 and 34020.
 
TI's graphics library had a bug when compiled at full optimization. A
memory mapped register was not declared "volatile", so the compiler
would optimize out the read on a spin loop, and hang if the condition
was not met on initial loop.
Robert Wessel <robertwessel2@yahoo.com>: Mar 30 01:13AM -0500


>http://stackoverflow.com/a/6972551/597607
 
>the 2200 series even had a C++ compiler. Or at least an eye-witness
>claims to have once seen the manual on-line. :-)
 
 
http://public.support.unisys.com/2200/docs/cp14.0/pdf/78310422-011.pdf
https://public.support.unisys.com/2200/docs/cp15.0/pdf/78310430-016.pdf
Bo Persson <bop@gmb.dk>: Mar 30 10:57AM +0200

On 2017-03-30 08:13, Robert Wessel wrote:
>> claims to have once seen the manual on-line. :-)
 
> http://public.support.unisys.com/2200/docs/cp14.0/pdf/78310422-011.pdf
> https://public.support.unisys.com/2200/docs/cp15.0/pdf/78310430-016.pdf
 
Oh, thanks! :-)
 
 
 
Bo Persson
Vir Campestris <vir.campestris@invalid.invalid>: Mar 30 09:49PM +0100

On 29/03/2017 13:54, Scott Lurndal wrote:
> four would be packed into a 36-bit word). On 48-bit systems[**], a word
> can be decomposed into 6 bytes using various instructions, but individual
> byte access to memory isn't supported.
 
_Was_ is the operative word. I first learned assembly on a DECSystem10.
The 36 bit words normally contained 5 7-bit characters, with a spare
bit. There was no byte access. I've also used ICL1900s (24 bit word, 4x6
bit characters) and a weird TI graphics processor where you could have a
packed array of items of any (small) number of bits. Handy when you want
to address a display with 8 greys per pixel. And yes, we did program
that one in C!
 
But this was all a long time ago...
 
Andy
Jorgen Grahn <grahn+nntp@snipabacken.se>: Apr 01 05:49AM

On Wed, 2017-03-29, Daniel wrote:
 
> UTF-8 is a Unicode byte encoding. It's something you send over a wire or
> serialize to a stream. It's not something the application programmer should
> have to be aware of.
 
Well, it's also something which looks like ASCII to any program which
doesn't look too closely. It was one of the selling points.
 
Surprisingly few of my programs look that closely. Parsing text files
works. Case-insensitive operations, sorting and alignment into
columns does not.
 
> }
 
> should loop over unicode codepoints, irrespective of the encoding of s
> (likely UTF-8).
 
Programs which *do* have to care would want that kind of support, yes.
 
(Note that I'm not claiming to be an expert on the subject. I'm still
puzzled by the implications, especially in mixed environments -- I have
25 years worth of data encoded as iso8859-1.)
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 30 01:44PM +0200

On 30-Mar-17 1:40 PM, Alf P. Steinbach wrote:
> [snip]
 
Sorry about the formatting, the non-aligned comments: it's Thunderbird
messing things up with its flowed format implementation.
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 30 01:40PM +0200

In C++03 perfect forwarding of a sequence of arguments of arbitrary
types, caused a combinatorial explosion in const versus non-const.
 
In C++11 and later even just writing a function that /accepts/ arbitrary
argument types, when it's desirable to accept std::initializer_list
literals such as `{1, 2, 3}`, causes a combinatorial explosion in
initializer_list (which must known to the compiler as such) versus others.
 
E.g. in order to be able to call
 
multi( {1, 2, 3}, {5, 6, 7} )
 
with up to 3 arguments, a bunch of silly overloads are apparently needed:
 
template< class... Collections >
class Multidimensional_view_
{
public:
Multidimensional_view_( Collections const&... )
{}
};
 
template< class... Collections >
inline $f make_multidimensional_view( ref_<const Collections>... c )
-> Multidimensional_view_< Collections... >
{ return Multidimensional_view_< Collections... >{ c... }; }
 
template< class... Collections >
inline auto multi( ref_<Collections>... c )
{ return make_multidimensional_view( c... ); }
 
template< class Value >
// i
inline auto multi(
ref_<const initializer_list<Value>> list
)
{ return make_multidimensional_view( list ); }
 
template< class Collection, class Value >
// ci
inline auto multi(
ref_<const Collection> c,
ref_<const initializer_list<Value>> list
)
{ return make_multidimensional_view( c, list ); }
 
template< class Value, class Collection >
// ic
inline auto multi(
ref_<const initializer_list<Value>> list,
ref_<const Collection> c
)
{ return make_multidimensional_view( list, c ); }
 
template< class Value_1, class Value_2 >
// ii
inline $f multi(
ref_<const initializer_list<Value_1>> list_1,
ref_<const initializer_list<Value_2>> list_2
)
{ return make_multidimensional_view( list_1, list_2 ); }
 
template< class Collection_1, class Collection_2, class Value >
// cci
inline auto multi(
ref_<const Collection_1> c_1,
ref_<const Collection_2> c_2,
ref_<const initializer_list<Value>> list
)
{ return make_multidimensional_view( c_1, c_2, list ); }
 
template< class Collection_1, class Value, class Collection_2 >
// cic
inline auto multi(
ref_<const Collection_1> c_1,
ref_<const initializer_list<Value>> list,
ref_<const Collection_2> c_2
)
{ return make_multidimensional_view( c_1, list, c_2 ); }
 
template< class Collection, class Value_1, class Value_2 >
// cii
inline auto multi(
ref_<const Collection> c,
ref_<const initializer_list<Value_1>> list_1,
ref_<const initializer_list<Value_2>> list_2
)
{ return make_multidimensional_view( c, list_1, list_2 ); }
 
template< class Value, class Collection_1, class Collection_2 >
// icc
inline auto multi(
ref_<const initializer_list<Value>> list,
ref_<const Collection_1> c_1,
ref_<const Collection_2> c_2
)
{ return make_multidimensional_view( list, c_1, c_2 ); }
 
template< class Value_1, class Collection, class Value_2 >
// ici
inline auto multi(
ref_<const initializer_list<Value_1>> list_1,
ref_<const Collection> c,
ref_<const initializer_list<Value_2>> list_2
)
{ return make_multidimensional_view( list_1, c, list_2 ); }
 
template< class Value_1, class Value_2, class Collection >
// iic
inline auto multi(
ref_<const initializer_list<Value_1>> list_1,
ref_<const initializer_list<Value_2>> list_2,
ref_<const Collection> c
)
{ return make_multidimensional_view( list_1, list_2, c ); }
 
template< class Value_1, class Value_2, class Value_3 >
// iii
inline auto multi(
ref_<const initializer_list<Value_1>> list_1,
ref_<const initializer_list<Value_2>> list_2,
ref_<const initializer_list<Value_3>> list_3
)
{ return make_multidimensional_view( list_1, list_2, list_3 ); }
 
How can this be avoided?
 
 
Cheers!,
 
- Alf
"Chris M. Thomasson" <invalid@invalid.invalid>: Mar 30 10:50PM -0700

On 3/25/2017 8:29 AM, fir wrote:
 
>>> This is why i am not seeking at discussing C++ with you on this forum.
 
>> Why are you here?
 
> ramine idiot is here to spam - to make advertisments of his idiot state to everybody
 
Damn.
bitrex <bitrex@de.lete.earthlink.net>: Mar 30 09:49AM -0400

Suppose I have a structure like this, where a wrapper class for a POD
struct has a static memory buffer, and on construction a copy of the POD
struct is placed in it via placement new. Then another class wraps that,
and using the CRTP ensures that each child class has its own copy of the
buffer (rather than one being shared among all the subclasses.)
 
And suppose I have a "constexpr" function that creates a constant vector
or array of these objects at runtime, initialized with the default
constructor. The classes inside just sit around holding their static
buffer and a nullptr.
 
And then I create a stack data structure holding pointers to those
objects. What I'd like to be able to do is pop a pointer off the stack,
dereference it, and assign it such that the operation constructs a new
wrapper holding my POD data "in place" in the vector/array of originally
default-initialized objects.
 
I was thinking "PODWrapper" could also hold a reference to the stack, so
that the destructor would push its own "this" pointer back on it when
the wrapper went out of scope.
 
I'm not sure the best way to write the copy constructors for the
following two classes such that dereferencing and assignment for this
type of class is possible, though, without ending up with memcpys that
try to use the same source and destination argument.
 
#include <cstring>
 
struct POD
{
int a;
int b;
int c;
};
 
template <template <typename> class Derived,
typename T>
struct PODHolder
{
virtual ~PODHolder() {}
 
operator T() const { return *pod_ptr_; }
T* operator&() const { return pod_ptr_; }
T* operator&(const PODHolder& other) const { return pod_ptr_; }
 
protected:
PODHolder() = default;
 
PODHolder(const T& pod) :
pod_ptr_(new (_pod_buf()) T(pod))
{}
 
PODHolder(const T* pod) : pod_ptr_(_pod_buf())
{
std::memcpy(pod_ptr_, pod, sizeof(T));
}
 
private:
static char* _pod_buf()
{
static auto buf = new char[sizeof(T)];
return &buf[0];
}
 
T *const pod_ptr_ = nullptr;
};
 
template <typename T>
struct PODWrapper : public PODHolder<PODWrapper, T>
{
PODWrapper() = default;
 
PODWrapper(const T& pod) :
PODHolder<PODWrapper,T>(pod) {}
 
PODWrapper(const T* pod) :
PODHolder<PODWrapper,T>(pod) {}
};
bitrex <bitrex@de.lete.earthlink.net>: Mar 30 09:53AM -0400

On 03/30/2017 09:49 AM, bitrex wrote:
 
> {
> static auto buf = new char[sizeof(T)];
> return &buf[0];
 
sorry, should be just "return buf;" here as buf is already a pointer.
bitrex <bitrex@de.lete.earthlink.net>: Mar 30 08:46PM -0400

On 03/30/2017 09:49 AM, bitrex wrote:
> struct is placed in it via placement new. Then another class wraps that,
> and using the CRTP ensures that each child class has its own copy of the
> buffer (rather than one being shared among all the subclasses.)
 
<snip>
 
Disregard, this code's all wrong.
 
Lemme get back to you...
Manfred <invalid@invalid.add>: Mar 30 12:24AM +0200


> I'm wondering if there are things with my Windows makefile
> that could be improved on:
 
> https://bitbucket.org/webenezer/onwards/src/7a925499bdaa2ce53df5401f255b2db9d6100bf0/makefile.windows?at=master&fileviewer=file-view-default
 
quicklz.obj: quicklz.h
$(CC) $(CFLAGS) -c quicklz.c
 
marshalling_integer.obj: marshalling_integer.hh
$(CC) $(CFLAGS) -c marshalling_integer.cc
 
The above should indicate the .c and .cc sources as dependencies
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 31 06:32PM

On Thu, 2017-03-30, Richard wrote:
 
>>> That sounds to me like you haven't tried to do what you suggest
 
>>What do I suggest?
 
> Do you not even know what you posted or can't read it above?
 
(I don't think you mean "copying the source code", since we have tools
like rsync to do that quickly these days.)
 
I suggested using a Makefile, but if you insinuate that I haven't
tried that, that's trivially false. Of course I have tried it; I use
make for all my projects. I've also used it to speed up and clarify
other projects' build processses, too. I remember speeding up one
build from 20 minutes to around twelve seconds.
 
I'm active looking for valid, technical reasons to use something else,
but haven't found any so far. Modulo the "I'm not Linus" bit;
projects like the Linux kernel definitely need something else.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
legalize+jeeves@mail.xmission.com (Richard): Mar 30 11:20PM

[Please do not mail me a copy of your followup]
 
Jorgen Grahn <grahn+nntp@snipabacken.se> spake the secret code
>>>to build, and building it there, is very small today.
 
>> That sounds to me like you haven't tried to do what you suggest
 
>What do I suggest?
 
Do you not even know what you posted or can't read it above?
 
 
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 30 07:08PM

On Wed, 2017-03-29, Richard wrote:
 
>>Perhaps, but the cost of copying the source code to whereever you want
>>to build, and building it there, is very small today.
 
> That sounds to me like you haven't tried to do what you suggest
 
What do I suggest?
 
> with any sizeable distribution or with any project that has a mildly
> complex build.
 
For the size, Make scales really well. One more source file, one more
line in the Makefile. (If you write decent Makefiles, which I do.)
 
For complexity, almost no systems have a complex build these days --
except when the build system itself is the source of complexity.
 
> In those situations where I've attempted to do what you suggest, it
> was significantly more painful than just running CMake. CMake
> supports this trivially out-of-the-box using the same source tree.
 
I don't quite understand. For someone else's project, you build with
whatever they offer. If that project uses CMake, you build using
CMake. (For me, it's usually a .configure script.)
 
If it was my project, I'd probably choose a plain Makefile.
 
Granted, there /are/ exceptions. Like the Linux kernel, where extreme
configurability is a must. Plain Make would not work there -- there's
no fixed dependency graph. But I'm not Linus, and I don't run any
projects like that. I won't place that kind of cost on a project
which doesn't need it, just because some /other/ project does.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
scott@slp53.sl.home (Scott Lurndal): Mar 30 05:29PM


>> Of course with regard to a graphical output or a GUI, there does
>> not even seem to be a TS in sight.
 
>What is a TS ?
 
First hit on google "C++ TS" gives the answer.
Lynn McGuire <lynnmcguire5@gmail.com>: Mar 30 12:20PM -0500

On 3/26/2017 3:30 PM, Stefan Ram wrote:
> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
...
> called »C++19/20« by some now).
 
> Of course with regard to a graphical output or a GUI, there does
> not even seem to be a TS in sight.
 
What is a TS ?
 
Thanks,
Lynn
ram@zedat.fu-berlin.de (Stefan Ram): Mar 30 12:16PM

>::std::vector< direction_t >directions{ 0, 1, 2, 3, 4, 5, 6, 7 };
>::std::vector< int >offset_y{ +1, +1, 0, -1, -1, -1, 0, +1 };
>::std::vector< int >offset_x{ 0, +1, +1, +1, 0, -1, -1, -1 };
 
I possibly should have used »::std::array« above, following
the guideline to prefer »::std::array« to »::std::vector«
when »::std::vectors« advanced features (resizing) are not
needed.
 
Also, I am told:
 
warning: declaration requires a global destructor [clang-diagnostic-global-constructors]
::std::vector< direction_t >directions{ 0, 1, 2, 3, 4, 5, 6, 7 };
^
. Don't know what to make of this.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: