Thursday, December 22, 2016

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

ruben safir <ruben@mrbrklyn.com>: Dec 21 11:48PM -0500

How is this fix ;)
 
 
/*
* =====================================================================================
*
* Filename: test.cpp
*
* Description: Threading Experiment
*
* Version: 1.0
* Created: 12/18/2016 12:46:51 PM
* Revision: none
* Compiler: gcc
*
* Author: Ruben Safir (mn), ruben@mrbrklyn.com
* Company: NYLXS Inc
*
* =====================================================================================
*/
 
#include <iostream>
#include <thread>
#include <mutex>
std::mutex medco;
std::mutex master;
 
namespace testing{
std::thread t[10];
class PIC
{
public:
PIC():source_index{&source[0]}
{
canvas_index = canvas;
std::cout << "Testing Source" << std::endl;
for(int i = 0; i<100; i++)
{
std::cout << i << " " << source[i] << std::endl ;
}
 
for(int i = 0; i < 10;i++)
{
t[i] = std::thread([this]{ readin(); });
std::cerr << i << ": Making a thread" << std::endl;
}
};
 

~PIC()
{
std::cerr << "In the destructor" << std::endl;
for(int i=0; i<10; i++)
{
t[i].join();
std::cerr << i << ": Joining a thread" << std::endl;
}
 
};

void readin()
{
char * loc_canvas_index;
char * loc_source_index;
sync_canvas_and_input(loc_canvas_index, loc_source_index);

for( int i = 9; i>=0; i-- )
{
*loc_canvas_index = loc_source_index[i];
std::cerr << i << ": Copy " << loc_source_index[i] << std::endl;
std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast<char>(*loc_canvas_index) << std::endl;
loc_canvas_index++;
}
 
};
void sync_canvas_and_input(char * &loc_canvas_index, char * &loc_source_index )
{
std::cout << "**LOCKING**" << std::endl;
std::lock_guard<std::mutex> turn(medco);
loc_canvas_index = canvas_index;
loc_source_index = source_index;
source_index += 10;
canvas_index += 10;
};
 
char * get_canvas()
{
return canvas;
}
char * get_canvas_index()
{
return canvas_index;
}
char * get_source_index()
{
return source_index;
}
 
private:
char * canvas = new char[100]{
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z',
'z', 'z','z','z','z','z','z','z','z','z'
};
char * canvas_index;
char source[100] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'
};
char * source_index;
};
}//end namespace
 
int main(int argc, char** argv)
{
testing::PIC fido;
for(int i = 0; i<100;i++)
{
std::cout << i << " Canvas Position " << fido.get_canvas()[i] << std::endl;
}
 
return 0;
}
ruben safir <ruben@mrbrklyn.com>: Dec 21 11:49PM -0500

On 12/21/2016 04:39 PM, Paavo Helde wrote:
> the cache line size, thus causing potentially significant performance
> penalties (probably not important for your toy example, but worth to
> mention).
 
 
That is a VERY cool observation!!!
 
Thank You
Paavo Helde <myfirstname@osa.pri.ee>: Dec 22 12:32PM +0200

On 22.12.2016 6:48, ruben safir wrote:
 
> How is this fix ;)
 
Yes, this makes a bit more sense, at least the mutex is really used for
mutual exclusion. A couple of remarks:
 
The functions get_canvas_index() and get_source_index() are lacking the
mutex lock. Any access to data which is concurrently modified needs a
mutex lock.
 
The function get_canvas() returns a pointer to the shared array without
any synchronization. This means race conditions. Instead, it should wait
on a std::condition_variable until all threads have fulfilled the task;
upon completion, each thread should increment a counter of completed
tasks under another mutex lock and notify the condition variable. (In
this toy example this waiting could be replaced by just joining all the
threads, but in real life you typically don't want to terminate your
service threads after each task.)
 
The mutex is defined in another place (a global!) than the protected
data. This is insane. The mutex should be together with the protected
data, preferably in its own section of private variables, clearly
documented:
 
private: // data members protected by medco
std::mutex medco;
char * canvas_index;
char * source_index;
 
private: // other data
// ...
 
The thread array t is also global, with no need, no protection, etc. As
soon as you create another instance of PIC it gets garbled.
 
HTH
Paavo
 
Sal LO <gegefffffff@gmail.com>: Dec 22 07:04AM -0800

On Wednesday, December 21, 2016 at 10:49:05 PM UTC+2, Popping mad wrote:
> std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast<char>(*loc_canvas_index) << std::endl;
> loc_canvas_index++;
> }
 
https://youtu.be/Al9bmstjUjc?t=2s
ruben safir <ruben@mrbrklyn.com>: Dec 22 11:00AM -0500


> https://youtu.be/Al9bmstjUjc?t=2s
 
I'm deaf and can't hear videos, but thanks.
ruben safir <ruben@mrbrklyn.com>: Dec 22 12:13PM -0500

On 12/22/2016 05:32 AM, Paavo Helde wrote:
> The functions get_canvas_index() and get_source_index() are lacking the
> mutex lock. Any access to data which is concurrently modified needs a
> mutex lock.
 
 
Wouldn't that cause a deadlock condition?
forumsmp@gmail.com: Dec 22 07:58AM -0800

The method DetermineAutoPilotMode is called at interval. FlightMode and DeviceID are determined at run time and is static through flight. SpaceShipMode and AutoPilotMode are dynamic - i.e change during the flight trajectory. I've scanned a handful of articles on how to restructure a design predicated on switch statements but not sure how the solutions apply to this case. I know switch statements are not necessarily bad but any recommendations on how to restructure this (design patterns ....) would be appreciated.
 
 
void SpaceShip::DetermineAutoPilotMode()
{
switch ( SpaceShipMode )
{
case Standby :
{
std::cout << " switch ( SpaceShipMode ) / Standby " << "\n";
AutopilotMode = Off;
}
break;
case Launch :
{
std::cout << " switch ( SpaceShipMode ) / Launch " << "\n";
AutopilotMode = Setup;
}
break;
case Flight :
{
switch ( AutopilotMode )
{
case Terminal :
{
std::cout << " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / Terminal " << "\n";
AutopilotMode = Decorrelation;
}
break;
case Off :
case Midcourse :
case Decorrelation :
case InitialTurn :
{
if ( CorrelationTimeDelay )
{
AutopilotMode = Terminal;
switch ( FlightMode )
{
case ALD :
{
std::cout
<< " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / InitialTurn / switch ( FlightMode ) / ALD " << "\n";
}
break;
case ALH :
{
std::cout
<< " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / InitialTurn / switch ( FlightMode ) / ALH " << "\n";
}
break;
default : break ;
};
}
else
{
switch ( DeviceID )
{
case DID1 :
case DID2 :
{
std::cout
<< " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / InitialTurn / switch ( DeviceID ) / DID1 | DID2 " << "\n";
}
break;
case DID3 :
{
std::cout
<< " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / InitialTurn / switch ( DeviceID ) / DID3 " << "\n";
}
break;
default : break ;
};
}
}
break ;
default : break ;
};
}
break;
case Unknown :
{
std::cout << " switch ( SpaceShipMode ) / Unknown " << "\n";
}
break;
default : break ;
};
}
iqrakbutt@gmail.com: Dec 21 10:58PM -0800

Hi,
 
Can anyone do C++ coding for below pseudocode. I will be really thankful.
 
INPUT:Ni, Hopmin ,i,SNi
OUTPUT:NHi
 
1: for(AllnodesinlistNi)do
2: ComputeCostij,j2Ni
3: endfor
4: j=firstelementofNi
5: while(NotendoflistNi)do
6: if(HOPmin,j+1==HOPmin,i)then
7: addjtoSNi
8: endif
9: j=nextelementofNi
10: endwhile
11: SortSNi(indescendingorderofCostij)
12: NHi=FirstelementofthelistSNi
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 08:26AM +0100

> [homework assignment redacted]
 
http://www.dietmar-kuehl.de/mirror/c++-faq/how-to-post.html#faq-5.2
 
Cheers & hth.!,
 
- ALf
Sal LO <gegefffffff@gmail.com>: Dec 22 07:05AM -0800

On Thursday, December 22, 2016 at 9:26:39 AM UTC+2, Alf P. Steinbach wrote:
 
> http://www.dietmar-kuehl.de/mirror/c++-faq/how-to-post.html#faq-5.2
 
> Cheers & hth.!,
 
> - ALf
 
https://youtu.be/Al9bmstjUjc?t=2s
Sal LO <gegefffffff@gmail.com>: Dec 22 07:04AM -0800

https://youtu.be/Al9bmstjUjc?t=2s
ram@zedat.fu-berlin.de (Stefan Ram): Dec 22 01:38AM

>I have a vector of std::vector<SomeType>. The precise number of vectors
>containing SomeType is unknown at runtime.
 
... is only known as late as runtime.
 
>How best to merge the set into a single std::vector<SomeType> with the
>SomeTypes arranged one after another, i.e. such that the "columns" of
>the first vector are transposed into a single row?
 
#include <initializer_list>
#include <iostream>
#include <ostream>
#include <vector>
#include <iterator>
#include <algorithm>
 
template< class T >
::std::vector< T >flatten
( ::std::vector< ::std::vector< T >> const & s )
{ ::std::vector< T > t;
auto bt = back_inserter( t );
for( auto const & v: s )
copy( begin( v ), end( v ), bt );
return t; }
 
int main()
{ using T = int;
::std::vector< ::std::vector< T >>s { { 1, 2 }, { 3 }};
::std::vector< T >t = flatten( s ); }
 
Additional exercise: Generalize this to the case where the
source vector contains »entries«, each of which at runtime
(polymorphically) can be either a number or a list of
numbers, nested to an arbitrary depth, and then flatten this!
 
Hint:
 
( SETQ FLATTEN
( LAMBDA( X )
( COND
( ( NULLP X ) '() )
( ( ATOMP X ) X )
( T ( APPEND
( COND
( ( ATOMP( CAR X ))( LIST( CAR X )))
( T ( FLATTEN( CAR X ))))
( FLATTEN( CDR X )))))))
ram@zedat.fu-berlin.de (Stefan Ram): Dec 22 12:55PM

> for( auto const & v: s )
> copy( begin( v ), end( v ), bt );
> return t; }
 
Another approach might be
 
...
using list = ::std::vector< T >;
auto product = accumulate
( begin( source ), end( source ), list {},
[]( list & l, list & r )
{ copy( begin( r ), end( r ), back_inserter( l ));
return l; } );
...
 
I hope that the temporary »list {}« lives long enough here,
before the product is being copied into »product«. Also, I
hope that in spite of the header »numeric«, accumulate can
cope with data which not ::std::is_arithmetic.
 
Of course, in practice, one should always measure whether
a »reserve« will make things faster (probably yes), but
above I wanted to keep the algorithm simple.
ram@zedat.fu-berlin.de (Stefan Ram): Dec 22 02:21PM

By trial and error I found out that I can multiply as
follows,
 
#include <iostream>
#include <ostream>
#include <functional>
 
int main()
{ ::std::cout << ::std::multiplies<>()( 2, 3 )<< '\n'; }
 
. Can »multiplies<>()(2,3)« be simplified?
(Without adding any definitions.)
 
Why was it designed that way, and not in way that it
can be used as:
 
{ ::std::cout << ::std::multiplies<>( 2, 3 )<< '\n'; }
 
or even
 
{ ::std::cout << ::std::multiplies( 2, 3 )<< '\n'; }
 
? I can surely define this myself as
 
#include <iostream>
#include <ostream>
 
template < class T >
T multiplies( T const l, T const r )
{ return l * r; }
 
int main()
{ ::std::cout << multiplies( 2, 3 )<< '\n'; }
 
, and such a function pointer could then also be passed to
algorithms AFAIK.
ram@zedat.fu-berlin.de (Stefan Ram): Dec 22 03:02PM

> []( list & l, list & r )
> { copy( begin( r ), end( r ), back_inserter( l ));
> return l; } );
 
And in C++17, one can then possibly use »:::std::reduce«
instead of »::std::accumulate«, which means that the
algorithm then possibly can be parallelized.
 
But here, parallelization would mean many more copies
and might actually slow down the process, like, totally.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 03:55PM +0100

On 22.12.2016 15:21, Stefan Ram wrote:
> #include <functional>
 
> int main()
> { ::std::cout << ::std::multiplies<>()( 2, 3 )<< '\n'; }
 
The C++11 standard doesn't specify a default for the template argument
so this is implementation-specific behavior, not guaranteed to compile.
 
Indeed the following, repeating the standard's definition of
`multiplies`, does not compile with either g++ or MSVC:
 
#include <iostream>
#include <ostream>
 
namespace my {
template< class T >
struct multiplies
{
T operator()(const T& x, const T& y) const { return 0; }
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
}
 
int main()
{ ::std::cout << ::my::multiplies<>()( 2, 3 )<< '\n'; }
 
But amazingly your example code does compile with both g++ and MSVC.
 
 
 
> Why was it designed that way, and not in way that it
> can be used as:
 
> { ::std::cout << ::std::multiplies<>( 2, 3 )<< '\n'; }
 
It's a type, not an object or function.
 
And it's a type because sometimes one needs the type, and this was
designed in C++98-times, without a `decltype` operator to produce a type.
 
 
> { ::std::cout << multiplies( 2, 3 )<< '\n'; }
 
> , and such a function pointer could then also be passed to
> algorithms AFAIK.
 
The function pointer can be less efficient because with a
`T::operator()` there is only one possibility for the `operator()`, so
inlining can be performed on each call, while with a function pointer
local analysis is not sufficient to say which function it is.
 
Also the functor approach is more general than a function, e.g. a
functor can carry or refer to state elsewhere, that its result depends on.
 
Cheers & hth.!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 05:09AM +0100

Typical usage in workgin toy program:
 
auto on( winapi::Message const& m ) noexcept
-> winapi::Lresult
override
{
#define WINAPI_MESSAGE_HANDLER_CLASS Main_window
switch( m.message_id )
{
WINAPI_DISPATCH( m, WM_COMMAND, on_wm_command );
WINAPI_DISPATCH( m, WM_PAINT, on_wm_paint );
WINAPI_DISPATCH( m, WM_SIZE, on_wm_size );
}
return subclassing_.original_processing( m );
#undef WINAPI_MESSAGE_HANDLER_CLASS
}
 
Definitions:
 
// These macros dispatch a window message to a member function via
the message
// cracker macros in <windowsx.h>. For example, message name
WM_PAINT yields
// a call via the HANDLE_WM_PAINT message cracker macro. See
<windows.h> for
// the required signatures for handlers; remove the window handle
argument.
 
// #define WINAPI_CRACKER_MACRO( message_name ) HANDLE_ ## message_name
 
#define WINAPI_DISPATCH_TO_MEMFN_VIA( message_cracker_macro,
memfunc, m ) \
message_cracker_macro ( \
this, m.wparam, m.lparam, std::mem_fn( &memfunc ) \
)
#define WINAPI_DISPATCH_TO_MEMFN( message_name, memfunc, m ) \
WINAPI_DISPATCH_TO_MEMFN_VIA( HANDLE_ ## message_name, memfunc, m )
 
#define WINAPI_DISPATCH( m, message_name, handler ) \
case message_name: return WINAPI_DISPATCH_TO_MEMFN_VIA( \
HANDLE_ ## message_name,
WINAPI_MESSAGE_HANDLER_CLASS::handler, m \
)
 
I've done this so many times in the past, with C++03. But I feel that
there must be some less unclean modern C++-ish way. Ideas?
 
Cheers!,
 
- Alf
bitrex <bitrex@de.lete.earthlink.net>: Dec 21 07:33PM -0500

I have a vector of std::vector<SomeType>. The precise number of vectors
containing SomeType is unknown at runtime.
 
How best to merge the set into a single std::vector<SomeType> with the
SomeTypes arranged one after another, i.e. such that the "columns" of
the first vector are transposed into a single row?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 02:09AM +0100

On 22.12.2016 01:33, bitrex wrote:
> vectors containing SomeType is unknown at runtime.
 
> How best to merge the set into a single std::vector<SomeType> with
> the SomeTypes arranged one after another,
 
Define "best".
 
 
> i.e. such that the "columns" of the first vector are transposed into
> a single row?
 
I don't understand this requirement
 
This is simple amortized linear time code to concatenate some vectors:
 
vector<int> a;
vector<int> b;
vector<int> c;
 
// ...
vector<int> all;
for( vector<int>* pv : {&a, &b, &c} )
{
all.insert( all.end(), pv->begin(), pv->end() );
}
 
To optimize this slightly you can `reserve` the requisite capacity for
the `all` vector before the loop.
 
 
Cheers & hth.,
 
- Alf
bitrex <bitrex@de.lete.earthlink.net>: Dec 21 08:28PM -0500

On 12/21/2016 08:09 PM, Alf P. Steinbach wrote:
 
>> i.e. such that the "columns" of the first vector are transposed into
>> a single row?
 
> I don't understand this requirement
 
To clarify I mean that if I have a vector of vector<string> and the two
vectors within contain respectively, front to back: {"H", "e", "l", "l",
"o"}, {"W", "o", "r", "l", "d"}
 
I would like the output vector to contain, front to back:
 
{"H", "e", "l", "l", "o", "W", "o", "r", "l", "d"}
 
 
> the `all` vector before the loop.
 
> Cheers & hth.,
 
> - Alf
 
Thanks. The only thing is I don't know exactly how many will end up
needing to be merged when writing the code, as the number the first
vector will contain is a run-time decision based on input data.
Daniel <danielaparker@gmail.com>: Dec 21 07:10PM -0800

On Wednesday, December 21, 2016 at 8:28:11 PM UTC-5, bitrex wrote:
 
> The only thing is I don't know exactly how many will end up
> needing to be merged when writing the code, as the number the first
> vector will contain is a run-time decision based on input data.
 
It doesn't matter. Given your input vector
 
std::vector<std::vector<std::string>> input;
 
however populated, the same algorithm applies:

size_t size = 0;
for (const auto& v : input)
{
size += v.size();
}
 
std::vector<std::string> output;
output.reserve(size);
for (const auto& v : input)
{
output.insert(output.end(), v.begin(), v.end());
}
 
Regards,
Daniel
Gareth Owen <gwowen@gmail.com>: Dec 21 11:34PM


>> Not true. Maths isn't a strong point, is it?
 
> This has nothing to do with maths; this is to do with analysing
> algorithmic complexity.
 
*facepalm* Analysing algorithms is a discipline of mathematics.
 
> See Wikipedia above.
 
Nevertheless, if you were capable of doing the mathematics, you'd see
that the average case performance is still O(N log N). The proof that
quicksort is O(N log N) on average is independent of the underlying data
structure. The reason for this is that choosing a sane pivot (median of
nine say) is O(n), and you can do a fixed number of different O(n) at
each recursive step you don't change the algorithmic complexity (but you
might screw up the constants so badly that it runs much slower than
mergesort).
 
The Wikipedia section on "Selection based pivoting" describes a scheme
based on this fact.
 
Note also that proviso in Wikipedia is about *stable* quicksort, and
std::list::sort is *not* required to be stable. Note also, that some
time ago I mentioned that mergesort is often preferred because it is
stable, where quicksort isn't.
 
> /Flibble
 
PS: Your killfile is broken
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 22 12:19AM

On 21/12/2016 23:34, Gareth Owen wrote:
 
>> This has nothing to do with maths; this is to do with analysing
>> algorithmic complexity.
 
> *facepalm* Analysing algorithms is a discipline of mathematics.
 
No, it isn't; it is a discipline of computer science and algorithmics.
 
[snip]
 
 
> std::list::sort is *not* required to be stable. Note also, that some
> time ago I mentioned that mergesort is often preferred because it is
> stable, where quicksort isn't.
 
Wrong. std::list::sort *is* required to be stable.
 
/Flibble
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 22 12:07AM +0100

> If you included links to your projects it would be
> more interesting.
 
Hmm, most of them should be used in the PM123 audio player for OS/2.
https://github.com/maazl/pm123/tree/master/src/utils/cpp
xstring.h, smartptr.h:int_ptr<>, container/btree.h and
container/vector.h:vector_int<> are the classes I mentioned.
 
No source code to be very proud of. Most of it is designed for the old
IBM VACPP compiler which did not support STL anyway. But it should be
functional, reasonable fast and memory conserving. Unfortunately this
application was never intended to be portable. I have ports of some
classes to other platforms and languages, but sorry, they are not open
source.
 
 
>> general purpose with as less as possible pitfalls. Performance is not
>> the only criterion.
 
> The containers are the weakest part of the STL in my opinion.
 
You forgot about iostreams, probably. They are even worse. ;-)
 
Compared to some other languages/class libraries the STL containers are
quite orthogonal. The .NET container classes and first of all the
interfaces are higgledy-piggledy.
 
 
Marcel
jonkalb@boost.org: Dec 21 03:45PM -0800

On Wednesday, December 21, 2016 at 4:28:13 AM UTC-8, Alf P. Steinbach wrote:
> capture `this`.
 
> Cheers & hth.,
 
> - Alf
 
Alf,
 
I want to congratulation you on understanding the question. Seeing your answer, I think you figured out the question and answered it correctly.
 
When I read the question, I had no idea what was being asked. I think the "valuable values" threw me most.
 
Jon
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: