- thread concurancy - 6 Updates
- nested switch statements - 1 Update
- Need Coding - 3 Updates
- comp - 1 Update
- Merge a std::vector - 4 Updates
- Standard function objects? - 1 Update
- Those dang window message dispatcher macros again, too unclean? - 1 Update
- Merge a std::vector - 4 Updates
- Qucksort for Linked List - 2 Updates
- Efficiency of standard containers - 1 Update
- lamda's in classes - 1 Update
| 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:
Post a Comment