- "Prepend" std::vector - 2 Updates
- std::byte - 12 Updates
- No _serious programming language lacks "evil" macros ! ! - 1 Update
- OT: Github - 2 Updates
- "Trip report: Winter ISO C++ standards meeting (Kona), C++17 is complete" by Herb Sutter - 2 Updates
- Writing assignmentoperators/copy ctrs for a CRTP class/simple stack allocator - 2 Updates
- My C++ exercise for today (2017-03-30) - 2 Updates
- Combinatorial arg explosion for function accepting initializer list literals - 2 Updates
Vir Campestris <vir.campestris@invalid.invalid>: Mar 30 09:59PM +0100 On 20/03/2017 07:40, Juha Nieminen wrote: > If you think you can, then prove it. Give me a function that will take > a linked list and a value, and will insert the value in the middle of > the list inexpensively. The insertion is cheap. It's finding the place that's expensive. Andy |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Mar 30 02:09PM -0700 On Thursday, March 30, 2017 at 4:59:20 PM UTC-4, Vir Campestris wrote: > > a linked list and a value, and will insert the value in the middle of > > the list inexpensively. > The insertion is cheap. It's finding the place that's expensive. Potentially. Link lists are not ideal in every situation, but if you are tracking through data and have anchors where you know where things need to be inserted, then it is very nice. It also makes parsing things easy. By creating a component link list, and then processing through the components, you can translating, re- arrange, delete, inject, as needed. Thank you, Rick C. Hodgin |
"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 |
Daniel <danielaparker@gmail.com>: Mar 29 07:24PM -0700 On Wednesday, March 29, 2017 at 8:58:29 PM UTC-4, Alf P. Steinbach 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. Any sequence of bytes except for the forward slash / or the NUL byte. That applies to Linux too. UTF-8 encoded filenames are fine, but so are filenames in any other encoding. As a practical matter, though, some applications may have difficulty with some encodings. I think it's fair to say that it's considered best practice in Linux to use UTF-8 encoded filenames. Daniel |
Daniel <danielaparker@gmail.com>: Mar 29 08:46PM -0700 On Wednesday, March 29, 2017 at 5:00:48 PM UTC-4, Mr Flibble wrote: > represented by a single scalar type are just as useless as variable > length UTF-8 encoded codepoints as far as wanting an atomic "character" > is concerned I don't understand your point. Given a std::string that contains UTF-8 encoded bytes, some operations can be performed on that std::string without iterating over the codepoints (or equivalently the UTF-8 character sequences), for instance, compare equal with another UTF-8 encoded string. 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. > I strongly disagree with your assertion that UTF-8 should only be used > during "serialization" I never asserted that. My own view is that UTF-8 is probably the preferred string _buffer_ encoding. wstring has been 32 bit on UNIX for a very long time, and never gained any significant adoption in applications that have had to support Unicode. I can't see u32string doing any better. > and that an application should be unaware of it I do believe that :-) Most modern languages have one string class with a standard string interface, not string, wstring, u16string, u32string, whole bunch of basic_string possibilities with different character types, char_traits, allocators. Instead of embuing encoding information in the type, they have an internal type, and functions getBytes(encoding), toBytes(encoding) to convert the internal representation from/to one of many possible external encoded types. There's enough prior experience now to suggest that that's the right approach. Daniel |
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 |
David Brown <david.brown@hesbynett.no>: Mar 30 10:00AM +0200 On 30/03/17 02:58, Alf P. Steinbach wrote: > 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. It has not - Mr. Flibble is wrong. Like all *nix systems, Linux filenames are a sequence of 8-bit characters terminated in \0. The only characters disallowed in the names are / (reserved for directories) and \0 (the terminator). It is up to the shell, file manager, desktop, etc., to interpret the filenames in any it wants. In the early days, ASCII was the common interpretation. Then people started using 8-bit code pages for different locales, before UTF-8 became dominant. In modern systems, UTF-8 is by far the most common encoding (with the huge majority of file names matching the ASCII encoding), but it is not required by the native filesystems or the OS. Some non-native filesystems, such as NTFS and VFAT, /do/ have requirements on character encoding (such as UCS-2 / UTF-16 / whatever half-made jumble MS picked for that particular version of the filesystem), and Linux will of course follow the rules there. |
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 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". |
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 |
Daniel <danielaparker@gmail.com>: Mar 30 05:30AM -0700 On Thursday, March 30, 2017 at 4:05:22 AM UTC-4, David Brown wrote: > 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.dd Good point. I hadn't thought of that, thanks. Daniel |
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. |
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 |
Jeff-Relf.Me @.: Mar 30 01:07PM -0700 |
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 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 . |
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 |
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. |
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. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 30 12:05PM I was reading an article by N. Wirth about "Program Development by Stepwise Refinement" from 1971. It is discussing the Eight Queens Problem and says: »The reader is strongly urged to try to find a solution by himself before embarking on the paper«. Argh! So, now, I couldn't read on, but had to solve the silly Eight Queens Problem myself first! I read it mentioned so very often, but never actually programmed a solution myself IIRC. So here it is in C++: #include <algorithm> #include <cassert> #include <iostream> #include <ostream> #include <vector> #include <string> using position_t = int; using direction_t = int; ::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 }; class board_t : public ::std::vector< position_t > { public: using ::std::vector< position_t >::vector; board_t(): board_t( 64 ){} int operator()( int const y, int const x ) const { return this->at( y * 8 + x ); } void set( position_t const position ) { assert( !this->at( position )); this->at( position )= 1; } void unset( position_t const position ) { assert( this->at( position )); this->at( position )= 0; } bool is_in_board( int const position ) const { return position >= 0 && position < 64; } bool is_in_board( int const y, int const x ) const { return y >= 0 && y < 8 && x >= 0 && x < 8; } bool conflict_with_other_position ( int const position_y, int const position_x ) const { for( direction_t const direction : directions ) { int const dy = offset_y.at( direction ); int const dx = offset_x.at( direction ); int pos_y = position_y; int pos_x = position_x; for( int distance = 0;; ++distance ) { pos_y += dy; pos_x += dx; if( !is_in_board( pos_y, pos_x ))break; if( ( *this )( pos_y, pos_x ))return true; }} return false; } bool conflict_with_other_position( position_t const position ) const { return conflict_with_other_position( position / 8, position % 8 ); } bool conflict_with_this_position( position_t const position ) const { return this->at( position ); } bool conflict( position_t const position ) const { assert( is_in_board( position )); if( conflict_with_this_position( position ))return true; return conflict_with_other_position( position ); } void print_cell_at( int const row, int const col ) const { ::std::cout <<( ( *this )( row, col )? 'W' : ':' ); } void print_end_of_line() const { ::std::cout << '\n'; } void print_all_cells_of( int const row ) const { for( int col = 0; col < 8; ++col )print_cell_at( row, col ); print_end_of_line(); } void print_all_rows() const { for( int row = 8; row > 0; ){ --row; print_all_cells_of( row ); }} void print() const { print_all_rows(); }}; static void print( board_t const & board ) { board.print(); ::std::cout << '\n'; } struct place_eight_queens { int number_of_queen {}; board_t board; void print_solution_or_set_next_queen( position_t const position ) { if( 8 == number_of_queen )print( board ); else place_next_queen( position ); } void set_this_queen( position_t const position ) { board.set( position ); print_solution_or_set_next_queen( position ); board.unset( position ); } void set_queen_if_no_conflict( position_t const position ) { if( !board.conflict( position ))set_this_queen( position ); } void try_all_positions( int const starting_position ) { for( position_t position = starting_position; position < board.size(); ++position ) set_queen_if_no_conflict( position ); } void place_next_queen( int const starting_position ) { ++number_of_queen; try_all_positions( starting_position ); number_of_queen--; } void place_queens() { number_of_queen = 0; int const starting_position = 0; place_next_queen( starting_position ); } void run() { place_queens(); }}; int main() { ::place_eight_queens{}.run(); } I have not yet compared the output with solutions from the literature, so I don't know whether it's correct. Problem: The function »conflict_with_other_position(int,int)« is way too long, but I was not yet able to find a elegant decomposition into several smaller function with less than three parameters each. |
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. |
"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 |
"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 |
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:
Post a Comment