Tuesday, February 28, 2017

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

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 05:36PM +0100

On 25.02.2017 16:13, Ben Bacarisse wrote:
> RESULTIS n
> $)
 
> In fact, that's how functions that need a block are defined.
 
Thanks! I was pretty sure it was supported, but I had some doubt
lingering. I never used the language.
 
 
[snip]
>> 2015. :)
 
> Where is the % operator being used? Is that masked by the $xyz stuff or
> is it in the header?
 
The `$defined` macro. I put the definition in a comment at top, but:
 
#define $invoked $e::impl::Gurkemeie{} % []()
 
Where `Gurkemeie` is an empty class defined in that namespace: its only
purpose is to guide Argument Dependent Lookup to find that `operator%`.
 
And now with your example to open my eyes, I see that this is just wrong
as a general definition. There should be a capture by reference. Thanks
again!
 
There is/will be a standard library invocation function in C++17,
¹`std::invoke`, and with C++11 the ²`std::reference_wrapper::operator()`
can invoke things. But these invokers put the invocation act, and any
arguments, textually after the lambda body. I feel that that's awkward,
that the most important information isn't up front, but later at the end.
 
Anyway, the starting point was `$invoked_with`, to define a way to add
RAII-like init and cleanup to a block of code, e.g. for automatic mutex
or a library envelope, without having to invent unnatural & unused names
for these objects. I implemented that first as a range based `for`, but
g++ complained with a warning about unused but assigned variable, even
when I made its constructor do things. Then I implemented it as a
conventional `for` loop, that iterated exactly once. But, during a visit
to a certain small room it occurred to me that if I did it with a lambda
with defaulted argument, then that same mechanism could be reused for
control structures in expressions, as with `$invoked`. I failed to see
that it would need a semicolon at the end, but I still think it's
better; just a single general mechanism.
 
Cheers!,
 
- Alf
 
Links:
¹ <url: http://en.cppreference.com/w/cpp/utility/functional/invoke>
² <url:
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator()>
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 01:15PM +0100

I'm not sure, but I think BCPL, which C was based on, supported control
structures within expressions; at least had curly braces in expressions?
 
Anyway, after C++11 and C++14 we can now do that in C++:
 
 
#include <p/expressive/use_weakly_all.hpp>
//
// #define $invoked $e::impl::Gurkemeie{} % []()
// #define $invoked_with( instantiation ) \ //
// $e::impl::Gurkemeie{} % []( decltype( instantiation ) =
instantiation )
 
#include <iostream>
$use_weakly_all_from( std );
 
struct Mutex
{
~Mutex() { cout << "Mutex::<destroy>" << endl; }
Mutex() { cout << "Mutex::<init>" << endl; }
};
 
struct Library_usage
{
~Library_usage() { cout << "Library_usage::<destroy>" << endl; }
Library_usage() { cout << "Library_usage::<init>" << endl; }
};
 
struct Tracing
{
~Tracing() { cout << "Tracing::<destroy>" << endl; }
Tracing() { cout << "Tracing::<init>" << endl; }
};
 
$just
{
$let sum = $invoked{ int s{}; for( int i = 1; i <= 8; ++i ) s += i;
return s; };
cout << sum << endl;
 
cout << endl;
$invoked_with( Tracing{} )
{
cout << "Hum!" << endl;
};
}
 
 
Here the % operator function is found via Argument Dependent Lookup and
invokes the specified lambda, producing an expression return value via
C++14 automatic return type deduction, and that works with MSVC 2015. :)
 
 
Cheers!,
 
- Alf
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 08:36AM -0800

> to refer to selectable objects, most often it requires to be allowed
> to refer to no object as well: typically such a variable is meant to
> address an object in a set, and typically sets can be empty.
 
No doubt that property is often true, but certainly it isn't
always true. A couple of counterexamples immediately come to
mind: one, a circular list (doubly linked) with a dummy node
pointing to the head and tail; and two, a 2-3 tree with internal
nodes (holding 1 value and 2 subtrees, or 2 values and 3
subtrees) and leaf nodes (holding 1 value or 2 values, and no
subtrees). Any external pointers to these structures are most
likely nullable, but the internal pointers should never be null
(and they do need to change as the structures grow and shrink).
 
It would be interesting to try a language experiment where
pointer types normally are not nullable, and a pointer type that
needs to be nullable would require writing, eg,
 
int *nullable p;
 
(I may have read this suggestion somewhere else, and if I could
remember if and where I would gladly give credit. I make no
claim for originality here.)
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 20 10:09PM

On Mon, 20 Feb 2017 13:39:43 -0800 (PST)
 
> I use those flags, but would rather not require users to
> have a C++ 2014 or 2017 compiler. Probably there are (or
> will be) others with the same request.
 
Brian,
 
This is meaningless and bizarre. If you want C++14 or C++17 features
you use the appropriate compiler flag. Whether or not C++11 was
incomplete is beside the point, as is whether or not C++11 should have
had a string_view. It didn't. C++17 does. So you use the C++17
compiler flag if you want it. Move on.
 
I am kind of left scratching my head over your lack of reasonable
logic. I think the religious mania of you and your nutjob colleague is
affecting your judgement.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 20 11:32PM

On Mon, 20 Feb 2017 15:03:03 -0800 (PST)
woodbrian77@gmail.com wrote:
[snip]
> from looking into my work. Same old same old from you for years,
> Chris. If you can't offer some constructive criticism, I suggest
> you say nothing.
 
That is outrageous. I have never even looked at your work (if by that
you mean your serializing product), let alone attacked it. Please
correct me by showing some post (any post) of mine which has referred to
it, or apologize if you are man enough to do so: I suspect you are not.
 
Your posts on this topic of "backporting" C++14/17 features to a C++11
compiler are ridiculous. But that is a separate matter.
 
I have now become cross with you.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 20 06:59PM

On Mon, 20 Feb 2017 10:12:13 -0800 (PST)
woodbrian77@gmail.com wrote:
[snip]
> for constructors" or at least make_unique in C++ 2011 compilers.
> I could live though, without that, but need the support for
> string_view.
 
What a weird suggestion. Why would anyone want to "backport" C++14/17
to C++11? It would no longer be C++11.
 
A more reasonable suggestion is that compilers should be incrementally
updated to C++14/C++17. Such a suggestion would be otiose: that is
already happening. It appears you may have failed to adopt the correct
compiler flags. gcc, clang and visual studio have supported
make_unique for some time (-std=c++14 for gcc/clang). Recent versions
of libstdc++ and libc++ also (as I understand it) support string_view
although I have never used it. No doubt VS will follow in the
relatively near future.
SG <s.gesemann@gmail.com>: Feb 28 04:17AM -0800

On Friday, February 24, 2017 at 8:52:16 PM UTC+1, Paul wrote:
> Please could someone link to (or provide) an example of copy-on-write in C++.
> I know what it means, but I'd like to see a simple example. I didn't
> really find one that looked convincing on a Google search.
 
A copy-on-write implementation of a type might be useful if otherwise
copying is too expensive. Internally, you could use std::shared_ptr<T>
for this. It offers a uniqueness check that allows you to make sure
that you won't modify something that is shared.
 
As a generic wrapper it might look like this:
 
template<class T>
class cow {
std::shared_ptr<T> ptr;
void make_unique();
public:
cow() : ptr(std::make_shared<T>()) {}
cow(T const& x) : ptr(std::make_shared<T>(x)) {}
cow(T && x) : ptr(std::make_shared<T>(std::forward<T>(x))) {}
T const& read() const { return *ptr; }
T& write() { if (!ptr.unique()) make_unique(); return *ptr; }
};
 
template<class T>
void cow<T>::make_unique() {
auto old = std::move(this->ptr);
this->ptr = std::make_shared<T>(*old);
}
 
If necessary, make_unique is called to create a copy. A copy is needed
if you want to modify the pointee but it is shared among multiple cow
instances. Note: I didn't test this. But I hope this helps anyways.
 
The use of std::shared_ptr allows you to follow "the rule of zero"
(you don't have to define any special member functions) and also
avoids some data race issues. Internally, the reference counter is
"atomic" which makes it safe to copy and destroy such shared_ptr
instances even if multiple threads share the same pointee. On that
note: const-access of such a T should also be thread-safe. If your T
has a mutable data member then chances are small that you can safely
use it inside cow<> in a multi-threaded program.
 
For special types (such as strings) you could probably do better. For
example, I liked the old libstdc++ (GCC) std::string implementation in
terms of memory layout. The size, capacity and reference counter
preceeded the string content in heap memory and a private data member
pointed directly to the first character. Only one allocation was
necessary. Their current implementation is different and does not use
copy-on-write anymore as far as I know.
 
Cheers!
sg
"Chris M. Thomasson" <invalid@invalid.invalid>: Feb 25 07:46PM -0800

On 2/25/2017 6:38 AM, Öö Tiib wrote:
>> which is the other part of that un-sharing-of-buffer operation.
 
> How recently you have profiled that? The lock-free atomic thingies seem
> more expensive than good old mutexes in multiprocessor systems in my tests.
 
A lot of lock-free techniques are way to expensive, and require too many
damn atomics and/or membars to get the job done.
 
A typical generic mutex usually needs two atomic ops and an
acquire/release membar paired relationship to keep the protected data
visible. If a lock free technique needs more membars atomics than its
mutex counterpart, then you are not going to really see a performance
enhancement wrt mutex never hitting its slowpath, blocking. However,
mutexs can block, and that can ruin their performance. Use locking
patterns wisely; Deadlock no more...
 
There are asymmetric locks, and non-blocking algorithms, but they are
more exotic.
 
;^)
 
 
Now, try to beat this sucker with a mutex based queue in a high
pressure, loaded environment. Stress the queue out to see what happens.
 
https://groups.google.com/d/topic/lock-free/acjQ3-89abE/discussion
 
You can use the original CAS based version by Dmitry Vyukov.
 
Or, my fast-pathed wait-free alteration:
 
<pseudo code, membars aside for a moment>
______________________________________________
struct cell { uint32_t ver; double state; };
 
uint32_t head = 0;
uint32_t tail = 0;
cell cells[N]; // N must be a power of 2
 
void init() {
for (uint32_t i = 0; i < N; ++i) cells[i].ver = i;
}
 
void producer(double state) {
uint32_t ver = XADD(&head, 1);
cell& c = cells[ver & (N - 1)];
while (LOAD(&c.ver) != ver) backoff();
c.state = state;
STORE(&c.ver, ver + 1);
}
 
double consumer() {
uint32_t ver = XADD(&tail, 1);
cell& c = cells[ver & (N - 1)];
while (LOAD(&c.ver) != ver + 1) backoff();
double state = c.state;
STORE(&c.ver, ver + N);
return state;
}
______________________________________________
 
Keep in mind, the tweak is wait-free on the atomics when fetch-and-add
is hardware based, and has no loops, like most CAS and/or all LL/SC.
Keep in mind that LOCK XADD is an example of a wait-free op, vs using
CMPXCHG in a software based loop on Intel...
 
Now, I also have a version of this with conditional waits here:
 
https://groups.google.com/forum/#!original/lock-free/acjQ3-89abE/idSNj77HsIIJ
thebtc@hotmail.com: Feb 27 04:52PM -0800

On Sunday, February 26, 2017 at 3:45:10 PM UTC-5, Paavo Helde wrote:
> specifier which would be actually needed in a C function declaration.
> So for the compiler is was just another C++ overload of some function
> which you declared but never called, so it was just ignored.
 
I see now, thank you so much for the tips that really cleared things up!
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 25 08:36PM


> Ok I considered what you both said and changed some things around.
 
You've fixed a couple of things and broken a couple of things that were
right before. In general, you can't write a program by trying things
out to see what happens!
 
The trouble is I don't know how much you want to learn about programming
or C++ or even if this is come course exercise. I'm going to point out
some things about your code and then show you a working example. If you
don't want to see a working example, just don't scroll down at the end
of this post.
 
> #include <iostream>
> #include <fstream>
> #include <string>
 
You don't need <string>
 
> char jobz = 'N'; // computes eigenvalues only
> char uplo = 'U'; // stores the upper triangle of a in an array a
> lapack_int n = 10; // the order of the matrix a
 
If you make this const you would be able to use it in the two array
declarations. It's generally better not to keep repeating numbers like
10, but to give them a name and use that instead.
 
> {2, 10, 6, 1, 10, 5, 7, 1, 10, 5},
> {11, 0, 10, 8, 0, 11, 2, 7, 5, 1}
> }; // the symmetric matrix a for which the eigenvalues will be found
 
This is the source of the error you report below. You have declared the
array a to be of pointers and you have then tried to put 100 number into
it. Remove the *.
 
> lapack_int lda = 10; // the leading dimension of the array a
> float* w[10]; // stores the eigenvalues
 
Remove the *. You want and array of floats.
 
> ofstream fout("eigenvaluesA.txt"); // title of text output
> lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
> lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
 
This is not a function call. The call does not have the types, but
instead lists the values to be passed. And (as you will see if you look
at my example) you don't have to name every single one of them.
 
> printing...a statement. The error I get now is "error: invalid
> conversion from 'int' to 'float*' [-fpermissive]" which I haven't been
> able to fix. Is that because float shouldn't be a pointer?
 
Spoiler alert: here is a working version (after the dots).
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
#include <iostream>
#include "lapacke.h"
 
int main(){
const lapack_int n = 10;
float a[n][n]= {
{1, 11, 7, 9, 7,11, 7, 9, 2,11},
{11, 4,10,10, 6, 2, 9, 6,10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6,10},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8},
{7, 6, 4, 8, 8,10, 5, 6,10, 0},
{11, 2, 4, 8,10, 9, 4, 3, 5,11},
{7, 9, 4, 3, 5, 4, 3,10, 7, 2},
{9, 6, 4, 5, 6, 3,10,11, 1, 7},
{2, 10, 6, 1,10, 5, 7, 1,10, 5},
{11, 0,10, 8, 0,11, 2, 7, 5, 1}
};
float w[n];
 
if (LAPACKE_ssyev(LAPACK_COL_MAJOR, 'N', 'U', n, a[0], n, w) == 0) {
for (int i = 0; i < n; i++)
std::cout << w[i] << " ";
std::cout << "\n";
}
}
 
 
--
Ben.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 25 11:10PM

thebtc@hotmail.com writes:
<snip>
 
> rather than passing them to the lapacke function as you did- because
> it gives me an opportunity to add extra comments and define everything
> in an obvious way to prevent marks from being removed.
 
Obviously do what you must to get the marks, but I'd like to offer an
alternative to the answer you've already had about this. I don't object
to comments, but I don't think that adding names like 'jobz' and 'uplo'
really helps much at all.
 
And as for the first argument, the named constant is arguably more
helpful in the call than in a variable:
 
LAPACKE_ssyev(LAPACK_COL_MAJOR, // hardly needs much comment
 
whereas
 
LAPACKE_ssyev(matrix_layout, // OK, but *what* layout is being used?
 
So, by all means document what you are doing. There is no need to avoid
comments just because you don't use extra variables and, when you do,
you can choose more expressive names than the ones chosen for the
function's prototype:
 
float eigenvalues[n];
LAPACKE_ssyev(LAPACK_COL_MAJOR,
'N', // compute only the eigenvalues
'U', // store only the upper triangle
n, // the dimension of the square input array
a[0], // the symmetric nxn input array, passed as a
// pointer to the first element (a[0] == &a[0][0])
n, // the leading dimension of the array
eigenvalues // where to store the computed results, passed as
// a pointer to the first element.
);
 
(My comments may not be good ones -- I don't know the library well.)
 
> So supposing if I wanted to define everything at the top explicitly, I
> would need to then include types and variable names in the lapacke
> function, is that correct?
 
I think you asking about the
 
lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
lapack_int n, float* a, lapack_int lda, float* w);
 
part that you included. That's a function prototype and it is needed,
but it's already in the "include file" you reference at the start:
 
#include "lapacke.h"
 
which will also define all the special types like lapack_int and so on.
 
> Because I noticed that when I did that, I
> didn't get an error.
 
But this then makes me unsure that I understood your question about
types are names.
 
> Also could you please explain why the lapacke
> function in your example ==0?
 
All of these functions indicate success by returning 0. You should
always check this sort of return value as printing anything from the w
array will be meaningless if LAPACKE_ssyev did not return 0.
 
--
Ben.
Christian Gollwitzer <auriocus@gmx.de>: Feb 25 10:14PM +0100

> rather than passing them to the lapacke function as you did- because
> it gives me an opportunity to add extra comments and define
> everything in an obvious way to prevent marks from being removed.
 
That is generally good advice. Especially with the obscure LAPACK
functions - they come from old FORTRAN code, which is very different
from C - it is hard to understand what the parameters are supposed to
do. Naming and commenting them makes it much easier, stick with that.
 
> Also could you please explain why the lapacke
> function in your example ==0?
 
The lapack function returns 0 if it was successful, so this tests if the
functino could compute the eigenvalues. Possible reasons for failure are
listed in the documentation; for example if you set the jobz to 'A'
(only 'N' or 'V' are allowed), then it does not compute anything and
returns -1.
 
If you are just learning, I want to point out some more subtlety from
Ben's solution. You have "float a[10][10]" and LAPACK expects a pointer
to the first element in this array "float *a". Ben passes
 
a[0]
 
which is correct, but obscure for a non-guru. Instead, you can write
 
&(a[0][0])
 
which means take the address of the element at 0,0 (the first element).
 
Christian
scott@slp53.sl.home (Scott Lurndal): Feb 24 01:41PM

>putted, so that means it shouldn't be an input but rather an output. So why=
> it exists inside LAPACKE_ssyev( ... , &w); I don't understand.
 
>Sorry, I'm very new to programming. I appreciate your time.
 
It seems evident that the W parameter is an output parameter. Since the
function will be storing a value indirectly through the pointer,
you don't need to initialize the variable before passing its address
to the function.
scott@slp53.sl.home (Scott Lurndal): Feb 23 08:22PM

>nt n, float* a, lapack_int lda, float* w );
 
>so I need to be able to input something for w. But I don't know what that i=
>s. Any help would be much appreciated. Thanks!
 
LAPACKE_ssyev( ... , &w);
Juha Nieminen <nospam@thanks.invalid>: Feb 22 07:37AM

> Juha ... why do I post?
 
Because you have been brainwashed, you think that your magical
incantations have supernatural powers to influence people, and
on top of that, you have a persecution complex and you enjoy the
hatred you get for your proselytizing. It reinforces your beliefs
and gives you comfort, in a sick twisted way. It makes you feel
pious.
 
That's why.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 21 09:42PM

On 21/02/2017 19:43, Rick C. Hodgin wrote:
>> follow doesn't exist...
 
> If you're absolutely certain that God doesn't exist (upper-case "G"),
> then you have nothing to worry about, Leigh.
 
Yes, I am absolutely certain that God (upper-case "G") doesn't exist.
 
/Flibble
Bo Persson <bop@gmb.dk>: Feb 22 11:50AM +0100

>> spams large amount of groups with bulk spam ...
 
> If you ever take the time to read what I post, fir, you'll find it's not
> spam. It is the way to forgiveness of sin, and eternal life.
 
If you don't believe it is a sin, you don't need any forgiveness.
 
Problem solved.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 11:09AM +0100

On 24.02.2017 09:29, helpseeker wrote:
> not. But I know its not needed to have the override keyword in cpp
> files. Is there a bad side to it though - to have override keyword in
> cpp file?
 
Your decision to use `override` should not be influenced by the kind of
file – whether header or implementation file like cpp.
 
The kind of file plays a rôle for the compiler's assumption of what
programming language the code is written in, and it plays a rôle for
your assumption about how the file will be used, e.g. that a header file
will be included and an implementation file used as the main code file
for a translation unit.
 
The by convention different usage means that one adopts some different
conventions in header files versus implementation files, e.g. for
include guards, use of `inline`, definitions of namespace scope
variables. But this does not extend to use of `override` or not. There
is no way that the different usage of different file types is related to
what `override` is about.
 
`override` is a safeguard against believing one overrides a base class'
member function that isn't there or isn't virtual, and it's a safeguard
against maintenance changing the signature of an overridden function,
e.g. by adding a defaulted argument. So, it's effectively a part of the
static type checking, even though it doesn't influence the type.
Essentially it says to the compiler, "this is what I intend, namely an
override, please check that for me", and clearly that has nothing to do
with file types whatsoever.
 
The cost is mainly that the syntax is awkward, with `override` at the
end of the function head. That can present a formatting problem. But
it's IMO a very small problem, and the safety is well worth it.
 
 
Cheers & hth.,
 
- Alf
Real Troll <real.troll@trolls.com>: Feb 21 10:30PM -0400

Just a brief note to let you all know that a troll has started posting
rubbish on C newsgroup so please refrain from responding to him. He
destroyed Linux NG <alt.os.linux> completely and now he is on:
<comp.lang.c>.
 
You have been warned.
Jerry Stuckle <jstucklex@attglobal.net>: Feb 22 09:08AM -0500

On 2/22/2017 7:09 AM, kushal bhattacharya wrote:
> Is it possible to run multiple queries in mysql c++ .If so how ?
> Actually when i run multiple queries with ';' i am getting error from mysql saying to refer to manual but when i run it in mysql directly it runs properly
 
First of all, this is a MySQL problem, not a C++ one, and should be
asked in a MySQL group such as comp.databases.mysql. And when you do,
you need to specify the exact code you're trying to execute and the
error message(s) you get back. As it is, any response would be a guess.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 02:03AM

>I confirmed, by writing my own little program for that, that you get a
>correct result. Although it is for index 999.999 in the sequence, when
>one considers fib(0) = 1, fib(1) = 1, fib(2) = 2, fib(3) = 3 and so on.
 
I tried to align my numbering with the sequence
 
oeis.org/A000045/b000045.txt
 
which starts:
 
0 0
1 1
2 1
3 2
4 3
5 5
6 8
 
and I also used this for my test code:
 
switch( i )
{ case 2: assert( result == "1"s ); break;
/* about 1997 lines omitted in this post */
case 2000: assert( result == "4224696333392304878706725602341482782579852840250681098010280137314308584370130707224123599639141511088446087538909603607640194711643596029271983312598737326253555802606991585915229492453904998722256795316982874482472992263901833716778060607011615497886719879858311468870876264597369086722884023654422295243347964480139515349562972087652656069529806499841977448720155612802665404554171717881930324025204312082516817125"s ); break; }
 
>I'm not sure how your code works, it seems to do strange
>things
 
It was a hasty translation from my JavaScript program,
but it uses some strange things so as to be fast.
 
>here's the expressive C++ dialect code
 
Usually I am the one who gets the flames for posting
"unreadable code", but now you are heroically diverting
the flames towards yourself!
 
>I did not take the trouble to split the addition loop into parts where
>the processing could be specialized for speed; I just used `-O3`. ;-)
 
I have edited your source code very slightly (see below),
and measured its execution time to be about 8 times the
execution time of my program. OTOH your code is much more
compact than mine. Your code, slightly modified:
 
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
 
using bigint = std::vector<int>;
 
static void addto( bigint & a, bigint const & b )
{
auto size_a = a.size();
auto size_b = b.size();
auto carry = 0;
for( decltype(size_a) i = 0; i < ::std::max( size_a, size_b ); ++i )
{ if( i >= size_a )a.resize( i + 1 );
a[ i ]+= carry +( i < size_b ? b[ i ]: 0 );
carry = a[ i ]/10;
a[ i ] -= 10 * carry; }
if( carry )a.push_back( carry ); }
 
int main()
{
auto const golden_ratio = 1.6180339887498948482045868343656381177203;
auto const golden_log = ::std::log10( golden_ratio );
auto const n = 100'000;
auto const n_digits = static_cast< bigint::size_type >
( ( n + 10. )* golden_log + 1 );
::std::clog << n_digits << " digits expected.\n";
 
auto a = bigint{ 1 }; a.reserve( n_digits );
auto b = bigint{ 0 }; b.reserve( n_digits );
 
for( decltype(+n) i = 0; i < n; ++i )
{ auto next = a;
addto( next, b );
a = ::std::move( b );
b = ::std::move( next ); }
 
for( auto i = b.size(); i > 0; )::std::cout << b[ --i ];
 
::std::cout << '\n'; }
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 06:10PM

>// $e::impl::Gurkemeie{} % []( decltype( instantiation ) =
>instantiation )
 
As once before, I recommend to either
 
o use traditional comments or
 
o use a Newsreader that will not break long lines or
 
o to limit the line length so that the lines are not
wrapped by the Newsreader.
bitrex <bitrex@de.lete.earthlink.net>: Feb 25 06:38PM -0500

Say I have a class, call it Bitmap, which holds onto a texture resource,
say "my_bitmap.png" which has to be allocated and deallocated through a
constructor and destructor the "old-fashioned" way via new and delete.
 
I then want to stick this class in a wrapper class that can be used as a
key-value type for boost::flyweight, using a smart pointer to wrap the
Bitmap class so that all objects in a graphics program that use
"my_bitmap.png" can refer to the one instance, and when all objects that
use it are destroyed the resource is release.
 
Is it more appropriate to use a std::unique_ptr or a std::shared_ptr in
the wrapper class in this circumstance?
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 08:06AM -0800


> Maybe if you are making a commentary or review on it.
> Just copypasting significant portions of the text does not
> fall under fair use.
 
If you look into the question more fully I think you will
find (a) that there are other factors that bear on the issue
besides the ones you listed, and (b) that the lines between
what is allowed and what is not allowed (ie, under "fair
use") are fuzzy rather than sharp. Here though my best
understanding is that this case is pretty clearcut.
 
Like I said, IANAL. Feel free to draw your own conclusions.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 24 12:19PM -0800

>> understanding is that this case is pretty clearcut.
 
> [...] I'm afraid it's increasingly difficult to make money as a
> book author. [...]
 
That's part of the reason I think a "Fair use" exception would be
allowed. The single page made available is unlikely to cause
someone who wants to buy the book not to buy it, but it might
very well convince some people to buy the book who would not have
otherwise. From the author's point of view, the page being
posted is pretty much all free advertsing, with negligible
downside.
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: