Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » AsyncWork<Vector<T>> fails due to lack of copy-constructor
AsyncWork<Vector<T>> fails due to lack of copy-constructor [message #52894] Mon, 06 January 2020 15:38 Go to next message
piotr5 is currently offline  piotr5
Messages: 103
Registered: November 2005
Experienced Member
I created AsyncWork<Vector<char>> and when I make use of the Get() member compiler complains Vector only has move-constructor.
is this a bug? CoWork.h reads:

template <class Ret>
class AsyncWork {
	template <class Ret2>
	struct Imp {
		CoWork co;
		Ret2   ret;
...
		const Ret2& Get()                            { return ret; }
	};
...
	Ret         Get()                               { ASSERT(imp); imp->co.Finish(); return imp->Get(); }


it's strange there is a 2nd template parameter for this class inside of AsyncWork.
sounds more like it was meant to be:
		Ret   ret;
...
		Ret2 Get()                            { return ret; }

and then use "Imp<const Ret&> imp;" in case Ret has copy-constructor?
or maybe rewrite to use if constexpr?
is there a speed-gain from using the copy-constructor?
I doubt there is one for Vector as return-type...

or did I make a mistake and AsyncWork is not for this kind of usage?
should I rewrite my code to use Thread?
Re: AsyncWork<Vector<T>> fails due to lack of copy-constructor [message #52895 is a reply to message #52894] Mon, 06 January 2020 22:32 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12157
Registered: November 2005
Ultimate Member
piotr5 wrote on Mon, 06 January 2020 15:38

or did I make a mistake and AsyncWork is not for this kind of usage?
should I rewrite my code to use Thread?


Well, I am not sure what your usage is, but yes, in general, I think using AsyncWork directly is probably not going to have intended effect.

That said, I think it should work with Vector.

Can you test this little change for me (I am too lazy to setup proper testing code now...):

template <class Ret>
class AsyncWork {
...
	const Ret&         Get()                               { ASSERT(imp); imp->co.Finish(); return imp->Get(); }


Can you eventually post here a complete testcase?

Mirek
Re: AsyncWork<Vector<T>> fails due to lack of copy-constructor [message #52896 is a reply to message #52895] Tue, 07 January 2020 00:14 Go to previous messageGo to next message
piotr5 is currently offline  piotr5
Messages: 103
Registered: November 2005
Experienced Member
In file included from /home/p/upp/uppsrc/Core/Core.h:342,
                 from /home/p/upp/uppsrc/Draw/Draw.h:6,
                 from /home/p/upp/uppsrc/RichText/RichText.h:4,
                 from /home/p/upp/uppsrc/CtrlCore/CtrlCore.h:4,
                 from /home/p/upp/uppsrc/CtrlLib/CtrlLib.h:4,
                 from /home/p/MyApps/arrow2circle/arrow2circle.h:4,
                 from /home/p/MyApps/arrow2circle/main.cpp:1:
/home/p/upp/uppsrc/Core/CoWork.h: In instantiation of 'Ret2 Upp::AsyncWork<Ret>::Imp<Ret2>::Get() [with Ret2 = Upp::Vector<unsigned char>; Ret = Upp::Vector<unsigned char>]':
/home/p/upp/uppsrc/Core/CoWork.h:195:99:   required from 'Ret Upp::AsyncWork<Ret>::Get() [with Ret = Upp::Vector<unsigned char>]'
/home/p/MyApps/arrow2circle/arrow2circle.h:28:18:   required from here
/home/p/upp/uppsrc/Core/CoWork.h:173:50: error: use of deleted function 'constexpr Upp::Vector<unsigned char>::Vector(const Upp::Vector<unsigned char>&)'
  173 |   Ret2 Get()                            { return ret; }
      |                                                  ^~~

similar if I add "pick(ret)" in place of "ret"
/home/p/upp/uppsrc/Core/CoWork.h: In instantiation of 'Ret2& Upp::AsyncWork<Ret>::Imp<Ret2>::Get() [with Ret2 = Upp::Vector<unsigned char>; Ret = Upp::Vector<unsigned char>]':
/home/p/upp/uppsrc/Core/CoWork.h:195:99:   required from 'Ret Upp::AsyncWork<Ret>::Get() [with Ret = Upp::Vector<unsigned char>]'
/home/p/MyApps/arrow2circle/arrow2circle.h:28:18:   required from here
/home/p/upp/uppsrc/Core/CoWork.h:173:59: error: cannot bind non-const lvalue reference of type 'Upp::Vector<unsigned char>&' to an rvalue of type 'std::remove_reference<Upp::Vector<unsigned char>&>::type' {aka 'U
    pp::Vector<unsigned char>'}

my code is just simple file-processing, here a short version:
#include <Core/Core.h>
#include <array>
using namespace Upp;

struct Parse {
	using CLASSNAME=Parse;
	std::array<AsyncWork<Vector<byte> >,3 > parser;
	FindFile path;
	
	void init(const String& p) {path.Search(p); for(auto&& i:parser) {i.Cancel();SetWork(i);};}
	Vector<byte> Work(const String& file);
	void SetWork(AsyncWork<Vector<byte> >& where) {if(path&&path.IsFile()&&path.GetLength()>0) {
		where.Do(THISFN(Work),path.GetPath());
		path.Next();
	};}
	void AddWork() { for(auto&& i:parser) if(i.IsFinished()) {
		auto out=i.Get();
		SetWork(i);
	}}
};

Vector<byte> Parse::Work(const String& file) {
	Vector<byte> out;
	return out;
}
CONSOLE_APP_MAIN
{
	Parse p;
	p.init(CommandLine()[1]);
}

this works with
		Ret Get()                            { return pick(ret); }

and also if I put "Ret&&" in place of "Ret" and use pick as above. using "std::forward<Ret2>(ret)" is a better idea here? (I compile with "-std=gnu++1z" and gcc-9.2.0)

Oh, and thanks for the hint. I'll try using CoWork to see if it's any better than my boilerplate...

[Updated on: Tue, 07 January 2020 00:41]

Report message to a moderator

Re: AsyncWork<Vector<T>> fails due to lack of copy-constructor [message #52898 is a reply to message #52896] Tue, 07 January 2020 15:16 Go to previous message
mirek is currently offline  mirek
Messages: 12157
Registered: November 2005
Ultimate Member
OK, in trunk, AsyncWork is now able to get by here, but you need to call Pick instead of Get.

That said, still not 100% sure what is the goal, but if you wanted to process files in parallel, I have cooked up a little example for you for future reference:

#include <Core/Core.h>

using namespace Upp;

CONSOLE_APP_MAIN
{
	FindFile ff("c:/xxx/csv/*.csv");
	Mutex lock;
	int total_lines = 0;
	CoDo([&] {
		int lines = 0;
		for(;;) {
			String path;
			{
				Mutex::Lock __(lock);
				while(ff && !ff.IsFile())
					ff.Next();
				if(!ff) {
					total_lines += lines;
					return;
				}
				path = ff.GetPath();
				ff.Next();
				Cout() << "About to process " << path << "\n";
			}
			FileIn in(path);
			while(!in.IsEof()) {
				in.GetLine();
				lines++;
			}
		}
	});
	
	Cout() << "Total number of lines is " << total_lines << "\n";
}
Previous Topic: Bugfix AsGate64() works correctly on totals > 2^31
Next Topic: Problem linking using RegExp
Goto Forum:
  


Current Time: Sat Jan 25 21:56:08 CET 2020

Total time taken to generate the page: 0.00804 seconds