Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/copy #6

Merged
merged 6 commits into from
May 4, 2016
Merged

Feature/copy #6

merged 6 commits into from
May 4, 2016

Conversation

apmccartney
Copy link
Member

Added a generic copy function for those occassion which you want to pass an lvalue to function accepting rvalue references, but don't want to move the data

@apmccartney apmccartney assigned jlconlin and whaeck and unassigned jlconlin May 2, 2016
/* functions */
/** @returns A copy of the argument value */
template< typename T >
T copy( const T& t ){ return t; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially the copy equivalent of the std::move function. I assume we'll be using this when we do not want to move an argument into an rvalue reference?

I am going to be the advocate of the devil here: if we use this too often, would it not be better to not use rvalue references (using a local variable instead) in a function call and explicitly use std::move when we want to move instead of copy? I think this is the more standard way (from what I see on the internet, I would assume this is the case) and as such it would be easier for other people to understand the code.

Copy link
Member Author

@apmccartney apmccartney May 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially the copy equivalent of the std::move function. I assume we'll be using this when we do not want to move an argument into an rvalue reference?

Yes, specifically an lvalue to a function requiring an rvalue reference argument.

if we use this too often, would it not be better to not use rvalue references (using a local variable instead) in a function call and explicitly use std::move when we want to move instead of copy?

I'm not sure I understand. Does the following example capture your suggestion?

Given a function with the prototype

void foo( expensiveType&& e);

you are suggesting

expansiveType bar;
auto copy = bar;
foo( std::move(copy) );
/* additional operations using bar */

as opposed to

expansiveType bar;
foo( utility::copy(bar) );
/* additional operations using bar */
The former is more expensive (without assuming certain compiler optimizations not guaranteed by the standard) and is more verbose. More over, the latter introduces a new variable to keep track of (and to name), as well as the potential to mistakenly use the `copy` variable in while still in an invalid state following the move operation. For most standard library container types, this results segmentation fault at runtime, which introduces extra pressure to test thoroughly

I think this is the more standard way (from what I see on the internet, I would assume this is the case)

In my experience, common wisdom is to specify these sort of prototypes using value semantics, e.g.

void foo( expensiveType e);

and when a move is desired, call to std::move, otherwise the value is implicit copied. My issue with this convention is that the default behavior (with respect to lvalues) is both

  • implicit
  • and expensive.
In my experience, when refactoring for performance working on NJOY and elsewhere, the largest gains are generally made by eliminating unnecessary implicit data copying of lvalues because of value semantics. By retaining the function prototype accepting an rvalue reference, a developer retain the ability to copy expensive types (by way of the generic copy), but can't do so accidentally.

Copy link
Member

@whaeck whaeck May 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was your last example:

void foo( expensiveType e);

and

expansiveType bar;
foo( std::move(bar) 

It is a good thing to have these discussions. I like your approach. We actually know we are copying/moving expensive types. Both approaches are essentially equivalent but differ in the sense that one will copy by default while the other will move by default unless we specifically say otherwise. And if we have to std::move all the time, we are probably doing it wrong.

@jlconlin
Copy link
Member

jlconlin commented May 3, 2016

Good job adding the tests for trim. What's going on with appveyor? I'm not sure those failures should prevent us from merging.

@apmccartney
Copy link
Member Author

@jlconlin The appveyor hook has been removed and the pull can now be merged.

@jlconlin jlconlin merged commit 3951be5 into master May 4, 2016
apmccartney added a commit that referenced this pull request Apr 14, 2017
a3e5adb constrain configuration types
470c254 directory installation correction
48ccecc regex error
44886a1 spacing in linker flags
cc89730 bugfix
6457dca rounding math removed and coverage extension
6c360a0 correction
35a3091 coverage in tests necessary for header-only libraries
edd43bb local changes
cbd8068 apple clang
8fe650a clang compliant debug flags
06fc1dc config
e6fb36d more updates
982fa8b update
b07c58c split
d840594 directory installation
5a03ea0 whitespace
4103d38 dependencies
75d0f1d subproject linking bug
5e9ac83 missung header extension
2657253 ignore path default
c486ab6 only verify version if version is available
9507100 bug
65038bd wrong order
cd179c1 bug
2cb9403 precedence
d9b76f1 bug in degenerate case
e86e3fd need more for subproject
5faa5b8 another bug
2493440 circular
d854e3e bug
50877ee correction
d6bac61 underscore keys
f93301c tweaks
2ff8fc0 external projects are hard
5bd040d Merge pull request #8 from njoy/refactor/generalize
ebb26a2 consider subprojects
0fd9a10 Merge pull request #6 from njoy/refactor/generalize
0d9c813 manual merge
22daf46 Merge pull request #5 from njoy/refactor/generalize
d19af43 njoy2016 testing/debugging
1527f74 debugged using njoy
64aca82 refactor
dce72af Merge pull request #3 from njoy/feature/collect_subprojects
d51b28a long lines
3164c69 don't build subproject executables
bae56cd correction
c10fdbd Correctly handle multiple test resources
f7c0ece offline script
e4b5ce8 better fortran module organization
fbd3876 removed project specific files
aad4441 testing work

git-subtree-dir: metaconfigure
git-subtree-split: a3e5adbd5c597d18898df0c63d2aeefa0dc3c230
@jlconlin jlconlin deleted the feature/copy branch July 24, 2018 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants