comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en
comp.lang.c++@googlegroups.com
Today's topics:
* Can't think of a good subject - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/ff410bf5e81204c2?hl=en
* Return by reference - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/f6dd94c3223a1dbf?hl=en
* Boost - 7 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
* Address one past the end of array - is this syntax a valid C++? - 4 messages,
3 authors
http://groups.google.com/group/comp.lang.c++/t/3660f2b84a4f1cb3?hl=en
* Naming conventions for private virtual methods - 5 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/cd78ce70e48273eb?hl=en
* a totally self balanced tree for unsigned integers... - 3 messages, 2
authors
http://groups.google.com/group/comp.lang.c++/t/f7fa6decb00d9969?hl=en
* Available C++ Libraries FAQ - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/3575ff8bbf7f732e?hl=en
==============================================================================
TOPIC: Can't think of a good subject
http://groups.google.com/group/comp.lang.c++/t/ff410bf5e81204c2?hl=en
==============================================================================
== 1 of 3 ==
Date: Thurs, Feb 13 2014 5:09 pm
From: Richard Damon
On 2/13/14, 5:29 PM, woodbrian77@gmail.com wrote:
>
> I'm looking for something analogous to this:
>
> while(fgets(lineBuf,300,Fl.FlHndl)){
> token=strtok(lineBuf," ");
> if(strcmp("Header",token)) break;
> cmw::File (strtok(nullptr,"\n ")).Marshal(buf);
> }
>
> That creates an anonymous File object.
>
perhaps
0, cmw:File(buf);
might work. The key is you need to make it so it can not be parsed as a
decleration.
== 2 of 3 ==
Date: Thurs, Feb 13 2014 7:28 pm
From: "K. Frank"
Hello Brian!
On Thursday, February 13, 2014 1:53:58 PM UTC-5, woo...@woo...com wrote:
> On Thursday, February 13, 2014 11:00:01 AM UTC-6, Bo Persson wrote:
> > woo...@woo...com skrev 2014-02-13 04:45:
> >
> > > The first (named) version works the way I want
> > > it to, and the second version, built with either
> > > gcc or clang doesn't. Both compilers are
> > > producing smaller text segments for the second
> > > version. And the results for that version
> > > (both compilers) are like nothing is being done
> > > in the loop.
> >
> > The second version also declares a named variable, buf. Parenthesis are
> > optional when declaring variables.
>
> OK, I see what you mean. Is there a way to
> tell the compiler I want an anonymous File
> object to be constructed using the buf object?
If you're willing to use C++11, you can use its
so-called uniform initialization:
cmw::File{buf};
(Note the curly braces instead of parentheses.)
The curly-brace initializer list is not compatible
with the expression being interpreted as declaring
buf a variable, and so avoids the most-vexing-parse
issue.
Good luck.
K. Frank
== 3 of 3 ==
Date: Thurs, Feb 13 2014 8:16 pm
From: woodbrian77@gmail.com
On Thursday, February 13, 2014 9:28:39 PM UTC-6, K. Frank wrote:
> Hello Brian!
>
> If you're willing to use C++11, you can use its
> so-called uniform initialization:
>
> cmw::File{buf};
>
> (Note the curly braces instead of parentheses.)
>
> The curly-brace initializer list is not compatible
> with the expression being interpreted as declaring
> buf a variable, and so avoids the most-vexing-parse
> issue.
>
I've heard of that a little, but didn't think of it
here. Have tested it and it's working.
I'm using some of the newer C++ features so using
another one isn't a problem. Thank you.
==============================================================================
TOPIC: Return by reference
http://groups.google.com/group/comp.lang.c++/t/f6dd94c3223a1dbf?hl=en
==============================================================================
== 1 of 3 ==
Date: Fri, Feb 14 2014 1:34 am
From: James Kanze
On Sunday, 9 February 2014 12:04:19 UTC, Marcel Müller wrote:
> On 09.02.14 12.50, Giuliano Bertoletti wrote:
> > which is the difference of calling?
> > ==================
> > MyClass c;
> > SubObject &sub = c.GetSubObject();
> > SubObject sub = c.GetSubObject();
> > ==================
> The second line creates a copy of SubObject. It is in fact another
> syntax for the following constructor call:
> SubObject sub(GetSubObject());
> This /might/ be expensive if copying SubObject is expensive. Furthermore
> changes to sub do not apply to c.GetSubObject().
Whether the changes should apply or not is the key. Reference
semantics and value semantics are two different things.
> In general you should prefer references for non-trivial data types
> unless you have good reasons not to do so.
Not for return values. References lock you in; once you return
a reference, you can never return a synthesized value. The
general rule is to return by value unless the intent is to
furnish access to an element of the object (e.g. things like the
operator[] of vector).
--
James
== 2 of 3 ==
Date: Fri, Feb 14 2014 1:38 am
From: James Kanze
On Sunday, 9 February 2014 12:21:40 UTC, Luca Risolia wrote:
> Giuliano Bertoletti wrote:
> > SubObject &sub = c.GetSubObject();
> Don't return references to sub objects.
That depends on the role of the class. Things like
std::vector<>::operator[] should certainly return a reference.
> To safely share (sub)objects in memory use smart pointers.
I can't really think of a situation where I'd want to "share" an
object. An object will normally either be independant (an
entity object, owned by no one), or part of another object.
--
James
== 3 of 3 ==
Date: Fri, Feb 14 2014 10:20 am
From: Luca Risolia
James Kanze wrote:
>> > SubObject &sub = c.GetSubObject();
>
>> Don't return references to sub objects.
>
> That depends on the role of the class. Things like
> std::vector<>::operator[] should certainly return a reference.
>> To safely share (sub)objects in memory use smart pointers.
>
> I can't really think of a situation where I'd want to "share" an
> object. An object will normally either be independant (an
> entity object, owned by no one), or part of another object.
Look at the example I gave in my other answer to this post to know what
sharing means with regard to the OP question. There you will certainly notice
that the term "share" is used in two standard function names at least. That
example should make the concept more clear to you and also answer to both your
previous observations.
==============================================================================
TOPIC: Boost
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
==============================================================================
== 1 of 7 ==
Date: Fri, Feb 14 2014 7:03 am
From: James Kanze
On Saturday, 18 January 2014 00:09:45 UTC, Ian Collins wrote:
> woodbrian77@gmail.com wrote:
> > On Friday, January 17, 2014 9:37:16 AM UTC-6, Alf P. Steinbach wrote:
> >> You can use the header-only sub-libraries without building Boost.
> >> However, the most useful of them are now part of the standard, e.g.
> >> shared_ptr.
> > I think std::array would be a better example. I still
> > don't find much need for shared_ptr.
> Maybe you don't but others certainly do!
I don't know. The way it's implemented often creates more
problems than it's worth.
Reference counted pointers seem irrelevant for a lot of
applications: some won't use any dynamic memory, except within
the standard containers, and many others will only use it for
entity objects, which have deterministic lifetimes for which
shared_ptr is totally irrelevant. And even in the few cases
where intensive use of reference counted pointers is relevant,
you probably want some sort of invasive counting, to avoid
errors. We experimented with `std::shared_ptr` when we moved to
C++11, but found that it didn't work for us, and went back to
our home written one.
--
James
== 2 of 7 ==
Date: Fri, Feb 14 2014 7:07 am
From: James Kanze
On Saturday, 18 January 2014 08:30:57 UTC, Nick Baumbach wrote:
> Ian Collins oratorically vehemently insists
> > On a more up to date machine with gcc:
> > time ./b2 -j 32
> > <stuff>
> > The Boost C++ Libraries were successfully built!
> > real 1m2.319s user 27m57.961s sys 1m49.214s
> Wow, -j 32 !! Say no more. Where did you find that 32 since at most I only
> can find 16, as 2 threads per core. Actually thread core, not real core.
> An i7 is still a 4 core, not sure how that threaded core is embedded into
> the hardware.
Maybe he's not using an Intel. Where I used to work (four and
a half years ago), I "inherited" a 32 core Sparc because it
wasn't fast enough for production (where 128 cores was the
minimum). And that was some time ago.
--
James
== 3 of 7 ==
Date: Fri, Feb 14 2014 9:29 am
From: Öö Tiib
On Friday, 14 February 2014 17:03:38 UTC+2, James Kanze wrote:
> On Saturday, 18 January 2014 00:09:45 UTC, Ian Collins wrote:
> > woodbrian77@gmail.com wrote:
> > > On Friday, January 17, 2014 9:37:16 AM UTC-6, Alf P. Steinbach wrote:
>
> > >> You can use the header-only sub-libraries without building Boost.
>
> > >> However, the most useful of them are now part of the standard, e.g.
> > >> shared_ptr.
>
> > > I think std::array would be a better example. I still
> > > don't find much need for shared_ptr.
>
> > Maybe you don't but others certainly do!
>
> I don't know. The way it's implemented often creates more
> problems than it's worth.
It seems to be implemented rather well. It is sort of
heavyweight smart pointer but not overly.
> Reference counted pointers seem irrelevant for a lot of
> applications: some won't use any dynamic memory, except within
> the standard containers, and many others will only use it for
> entity objects, which have deterministic lifetimes for which
> shared_ptr is totally irrelevant. And even in the few cases
> where intensive use of reference counted pointers is relevant,
> you probably want some sort of invasive counting, to avoid
> errors. We experimented with `std::shared_ptr` when we moved to
> C++11, but found that it didn't work for us, and went back to
> our home written one.
If the objects for 'std::shared_ptr' are allocated with
'make_shared' then I haven't observed much performance
difference with intrusive ref-counting. What are the key features
it lacks? Issue may be that some functionality it has (like dynamic
"deleter" or "weak count") are unneeded for particular application
but errors it does not seem to have.
== 4 of 7 ==
Date: Fri, Feb 14 2014 11:12 am
From: Paavo Helde
Öö Tiib <ootiib@hot.ee> wrote in
news:5499b6d8-5127-428a-96a1-44df98c1a473@googlegroups.com:
> If the objects for 'std::shared_ptr' are allocated with
> 'make_shared' then I haven't observed much performance
> difference with intrusive ref-counting. What are the key features
> it lacks?
Intrusive smartpointers have a convenient property that they can be created
from plain pointers (like 'this') or references. Let's say you are changing
some function which currently has only a pointer or reference to the
object, and want to call some other function which expects a smartpointer,
or want to store a smartpointer for later use. With intrusive smartpointers
this is a no-braner, otherwise it becomes a PITA to pass smartpointers
through all those functions which actually do not need them.
Of course, this style works best if *all* objects of the given class can be
accessed via smartpointers (all objects are allocated only dynamically, for
example). This requirement may appear as a drawback in some cases.
Cheers
Paavo
== 5 of 7 ==
Date: Fri, Feb 14 2014 12:03 pm
From: Ian Collins
James Kanze wrote:
> On Saturday, 18 January 2014 00:09:45 UTC, Ian Collins wrote:
>> woodbrian77@gmail.com wrote:
>
>>> I think std::array would be a better example. I still
>>> don't find much need for shared_ptr.
>
>> Maybe you don't but others certainly do!
>
> I don't know. The way it's implemented often creates more
> problems than it's worth.
Like any software tool, it depends how you use it. Smart pointers and
reference counting were a couple of the C++ tricks that first pulled me
over from C and I've been using them ever since.
> Reference counted pointers seem irrelevant for a lot of
> applications: some won't use any dynamic memory, except within
> the standard containers, and many others will only use it for
> entity objects, which have deterministic lifetimes for which
> shared_ptr is totally irrelevant. And even in the few cases
> where intensive use of reference counted pointers is relevant,
> you probably want some sort of invasive counting, to avoid
> errors.
Invasive counting should have a slight performance edge, but the
programmer doesn't always have control of the type contained by the
pointer. In cases where objects are manipulated more often than that
are allocated, the advantages are less obvious. Most of my use cases
for std::shared_ptr are build a tree, process the tree data where the
process phase dominates the run time.
Care to explain "to avoid errors"?
> We experimented with `std::shared_ptr` when we moved to
> C++11, but found that it didn't work for us, and went back to
> our home written one.
I went the other way...
--
Ian Collins
== 6 of 7 ==
Date: Fri, Feb 14 2014 1:17 pm
From: Öö Tiib
On Friday, 14 February 2014 21:12:58 UTC+2, Paavo Helde wrote:
> Öö Tiib <ootiib@hot.ee> wrote in
> news:5499b6d8-5127-428a-96a1-44df98c1a473@googlegroups.com:
>
> > If the objects for 'std::shared_ptr' are allocated with
> > 'make_shared' then I haven't observed much performance
> > difference with intrusive ref-counting. What are the key features
> > it lacks?
>
> Intrusive smartpointers have a convenient property that they can be created
> from plain pointers (like 'this') or references.
Boost has 'shared_from_this<>()' but I have never needed it. Some Boost.Asio
examples use it.
> Let's say you are changing
> some function which currently has only a pointer or reference to the
> object, and want to call some other function which expects a smartpointer,
> or want to store a smartpointer for later use. With intrusive smartpointers
> this is a no-braner, otherwise it becomes a PITA to pass smartpointers
> through all those functions which actually do not need them.
Is it some sort of mid-way refactoring where we have raw pointers in mix
with smarts?
> Of course, this style works best if *all* objects of the given class can
> be accessed via smartpointers (all objects are allocated only dynamically,
> for example). This requirement may appear as a drawback in some cases.
Yes, typically constructor is protected and there are factories that
'make_shared'. What is the drawback with that approach?
== 7 of 7 ==
Date: Fri, Feb 14 2014 2:49 pm
From: Paavo Helde
Öö Tiib <ootiib@hot.ee> wrote in
news:6614aa58-859d-4a24-9cab-adb713b48ae2@googlegroups.com:
> Yes, typically constructor is protected and there are factories that
> 'make_shared'. What is the drawback with that approach?
The drawback is that sometimes you want a temporary object which could be
an automatic object on the stack, but you cannot have that (as the
constructor is protected, for good reasons). I understand this is only a
performance issue, but in the spirit it is against the zero overhead
principle of C++.
Cheers
Paavo
==============================================================================
TOPIC: Address one past the end of array - is this syntax a valid C++?
http://groups.google.com/group/comp.lang.c++/t/3660f2b84a4f1cb3?hl=en
==============================================================================
== 1 of 4 ==
Date: Fri, Feb 14 2014 7:30 am
From: James Kanze
On Saturday, 1 February 2014 17:23:39 UTC, Peter wrote:
> Assume we have an array:
> int arr[5];
> It's legal to refer to address arr + 5, but, of course,
> illegal to refer to element arr[5] as it's not part of the
> array. However, arr + n is equivalent to &arr[n].
No it's not. They're only equivalent if the expression "arr[n]"
is a valid expression.
> My question
> is: does this equivalence also hold for an edge case of
> n = 5 (or, generally, n equal to number of elements of array)?
> While there's nothing wrong with arr + 5, &arr[5] looks highly
> suspicious: it looks like in the first step arr[5] is
> evaluated (which introduces an undefined behaviour) which
> would mean the expression as a whole is undefined.
Exactly.
> Does the
> equivalence still hold in this special case?
No. "arr + 5" is legal, and corresponds to a pointer one beyond
the end of the array. "&arr[5]" is undefined behavior.
C has a special rule to allow "&arr[5]". Back before C++03 (and
even before C++98, I think), there was some discussion about
allowing this in C++, but in the end, the special case was not
adopted. (I think part of the motivation for not adopting it is
that you couldn't make it work with user defined containers,
like std::vector. Something like:
std::vector<int> v(5);
int* p = &v[5];
will crash, at least in debug mode, in all of the
implementations I use.)
--
James
== 2 of 4 ==
Date: Fri, Feb 14 2014 7:35 am
From: James Kanze
On Saturday, 1 February 2014 22:36:06 UTC, Victor Bazarov wrote:
[...]
> I would not be surprised at the validity of this after I've learned that
> initializing a reference by dereferencing a null pointer is now legal.
> *nullptr creates a special kind of reference, and the only useful
> operation you can do with it is to take its address, which in turn
> should give you null, as I understand it.
Just curious, but where did you get this information from?
I can't find it in the standard (looking in the obvious places,
which isn't always enough).
--
James
== 3 of 4 ==
Date: Fri, Feb 14 2014 8:12 am
From: Victor Bazarov
On 2/14/2014 10:35 AM, James Kanze wrote:
> On Saturday, 1 February 2014 22:36:06 UTC, Victor Bazarov wrote:
> [...]
>> I would not be surprised at the validity of this after I've learned that
>> initializing a reference by dereferencing a null pointer is now legal.
>> *nullptr creates a special kind of reference, and the only useful
>> operation you can do with it is to take its address, which in turn
>> should give you null, as I understand it.
>
> Just curious, but where did you get this information from?
> I can't find it in the standard (looking in the obvious places,
> which isn't always enough).
I can't give you the exact source, unfortunately, and I am sorry. All I
can remember is that it was mentioned here, discussed in some thread,
and at the time my claim of undefined behavior of initializing a
reference by dereferencing a null pointer was contradicted, and upon
investigating I found that the lvalue to rvalue conversion that used to
be necessary and was the cause of the UB in such a case was not any
longer a requirement (or it was that I incorrectly remembered that
conversion was needed). And in a blink of an eye, so to speak, UB was
not there anymore.
I'm likely too gullible when C++ is concerned. Next you're going to
tell me that atoi is not a standard function, and I'll believe it. :-)
V
--
I do not respond to top-posted replies, please don't ask
== 4 of 4 ==
Date: Fri, Feb 14 2014 8:42 am
From: Mr Flibble
On 14/02/2014 16:12, Victor Bazarov wrote:
> On 2/14/2014 10:35 AM, James Kanze wrote:
>> On Saturday, 1 February 2014 22:36:06 UTC, Victor Bazarov wrote:
>> [...]
>>> I would not be surprised at the validity of this after I've learned that
>>> initializing a reference by dereferencing a null pointer is now legal.
>>> *nullptr creates a special kind of reference, and the only useful
>>> operation you can do with it is to take its address, which in turn
>>> should give you null, as I understand it.
>>
>> Just curious, but where did you get this information from?
>> I can't find it in the standard (looking in the obvious places,
>> which isn't always enough).
>
> I can't give you the exact source, unfortunately, and I am sorry. All I
> can remember is that it was mentioned here, discussed in some thread,
> and at the time my claim of undefined behavior of initializing a
> reference by dereferencing a null pointer was contradicted, and upon
> investigating I found that the lvalue to rvalue conversion that used to
> be necessary and was the cause of the UB in such a case was not any
> longer a requirement (or it was that I incorrectly remembered that
> conversion was needed). And in a blink of an eye, so to speak, UB was
> not there anymore.
Bullshit mate: dereferencing null pointers is UB, period.
/Flibble
==============================================================================
TOPIC: Naming conventions for private virtual methods
http://groups.google.com/group/comp.lang.c++/t/cd78ce70e48273eb?hl=en
==============================================================================
== 1 of 5 ==
Date: Fri, Feb 14 2014 8:27 am
From: Daniel
I know, nobody likes this kind of question, but there aren't many questions these days, so ...
Consider a case of private virtual inheritance where the motivation is to have overloading on the preferred method name "value".
class base
{
public:
void value(int val)
{
// calls value_
}
void value(long val)
{
// calls value_
}
void value(long long val)
{
// calls value_
}
private:
virtual void value_(long long val) = 0;
};
class derived : public base
{
private:
// implements value_
};
Can anyone suggest a reasonable naming convention for the overridable private method value_? I've seen variants of "doValue", "value_long_long", and "value_event". Any commonly used conventions?
Thanks,
Daniel
== 2 of 5 ==
Date: Fri, Feb 14 2014 8:53 am
From: Victor Bazarov
On 2/14/2014 11:27 AM, Daniel wrote:
> I know, nobody likes this kind of question, but there aren't many
questions these days, so ...
>
> Consider a case of private virtual inheritance where the motivation
> is
There is no private virtual inheritance in your post, just so we talk
about the same thing, a private virtual inheritance is this relationship
between classes A and B:
class A { ... };
class B : virtual A { ... };
to have overloading on the preferred method name "value".
>
> class base
> {
> public:
> void value(int val)
> {
> // calls value_
> }
> void value(long val)
> {
> // calls value_
> }
> void value(long long val)
> {
> // calls value_
> }
> private:
> virtual void value_(long long val) = 0;
> };
>
> class derived : public base
> {
> private:
> // implements value_
> };
>
> Can anyone suggest a reasonable naming convention for the overridable
> private method value_? I've seen variants of "doValue",
> "value_long_long", and "value_event". Any commonly used conventions?
From the implementation 'value' here is a "setter", so it might make
sense to indicate that.
Another argument is that the overloaded function shall be specific to
each class deriving from 'base', so it might make sense to add
"specific" to it (either as a suffix or as a prefix).
And of course I admit that I am not aware of any convention you're
alluding to in your message. If there exists something of that sort, I
have never come across it, or cannot recall such an occurrence.
V
--
I do not respond to top-posted replies, please don't ask
== 3 of 5 ==
Date: Fri, Feb 14 2014 9:34 am
From: Paavo Helde
Daniel <danielaparker@gmail.com> wrote in
news:0be77c62-9923-4477-97ad-1f9a0f35c3c3@googlegroups.com:
> I know, nobody likes this kind of question, but there aren't many
> questions these days, so ...
>
> Consider a case of private virtual inheritance where the motivation is
> to have overloading on the preferred method name "value".
>
> class base
> {
> public:
> void value(int val)
> {
> // calls value_
> }
> void value(long val)
> {
> // calls value_
> }
> void value(long long val)
> {
> // calls value_
> }
> private:
> virtual void value_(long long val) = 0;
> };
>
> class derived : public base
> {
> private:
> // implements value_
> };
>
> Can anyone suggest a reasonable naming convention for the overridable
> private method value_? I've seen variants of "doValue",
> "value_long_long", and "value_event". Any commonly used conventions?
FWIW, I am naming private/protected virtual functions (this means most
virtual functions) with prefix Do. In your example it would be something
like DoSetValue(). However, I would not have multiple functions calling
it, instead there would be a single nonvirtual SetValue() which is
checking pre- and postconditions etc. If overloads are indeed needed, I
would probably need to invent a third name for them.
hth
Paavo
== 4 of 5 ==
Date: Fri, Feb 14 2014 9:46 am
From: Öö Tiib
On Friday, 14 February 2014 18:27:52 UTC+2, Daniel wrote:
> Can anyone suggest a reasonable naming convention for the overridable
> private method value_? I've seen variants of "doValue",
> "value_long_long", and "value_event". Any commonly used conventions?
I prefer to avoid setters; when still needed I prefer to indicate that
in name as "set value". Getters I prefer to name just "value". For
private virtual I use prefix "do" so for your example ... "do set value".
Note that it is about naming so usually I follow whatever conventions
code-base under work already uses. There are no "ultimate"
conventions. There can be convention or there can be awful mess caused
by people with different "ultimates".
== 5 of 5 ==
Date: Fri, Feb 14 2014 10:28 am
From: Daniel
On Friday, February 14, 2014 11:53:14 AM UTC-5, Victor Bazarov wrote:
>
> From the implementation 'value' here is a "setter", so it might make
> sense to indicate that.
>
> Another argument is that the overloaded function shall be specific to
> each class deriving from 'base', so it might make sense to add
> "specific" to it (either as a suffix or as a prefix).
>
That's helpful, thanks,
Daniel
==============================================================================
TOPIC: a totally self balanced tree for unsigned integers...
http://groups.google.com/group/comp.lang.c++/t/f7fa6decb00d9969?hl=en
==============================================================================
== 1 of 3 ==
Date: Fri, Feb 14 2014 1:44 pm
From: "Chris M. Thomasson"
I do not even want to go into why James tried to post this as his own!
:^/ GRRRR!!!!! #$%#$% FUC32432KL#$@#$@
Anyway, He made a fatal mistake! My name is in my cryptic MACROS!!!!
Take a look:
https://groups.google.com/d/topic/comp.programming/tjlLW7fFmsE/discussion
HAW HAW!!!!!
:^)
Anyway, I need to use it now for a database.
== 2 of 3 ==
Date: Fri, Feb 14 2014 2:51 pm
From: "Chris M. Thomasson"
"Chris M. Thomasson" wrote in message
news:ldm2of$p64$1@speranza.aioe.org...
[...]
Here is the link to the relevant code:
https://groups.google.com/forum/#!msg/comp.programming/tjlLW7fFmsE/fXdyD9QcG2cJ
notice my name in TREE_NAME?
Grrr!!!
____________________________________________________
typedef unsigned int tree_key;
#define BITS 4
#define MASK ~(UINT_MAX << BITS)
#define NODES (MASK + 1)
struct tree
{
struct tree* nodes[NODES];
tree_key key;
};
struct tree*
tree_find(struct tree* root,
tree_key origin_key)
{
tree_key key = origin_key;
while (root)
{
if (root->key == origin_key) break;
root = root->nodes[key & MASK];
key >>= BITS;
}
return root;
}
Is that something like what you are thinking of Ben?
Here is source code for a quick test program that implements the new
algorithm:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#define QUOTEX(t)#t
#define QUOTE(t)QUOTEX(t)
#define HASH_DEPTH 1
#define HASH(k) ((k) & (HASH_DEPTH - 1))
#define TREE_BITS 4
#define TREE_MASK ~(UINT_MAX << TREE_BITS)
#define TREE_NODES (TREE_MASK + 1)
#define TREE_SEARCH_ALGO_BINARY 0
#define TREE_SEARCH_ALGO_BIT 1
#define TREE_SEARCH_ALGO TREE_SEARCH_ALGO_BIT
#if (TREE_SEARCH_ALGO == TREE_SEARCH_ALGO_BINARY)
# undef TREE_NODES
# define TREE_NODES 2
# define TREE_NAME "Normal Binary Tree\n\n\n"
#else
# define TREE_NAME "Chris' %lu-Ary %lu-Bit Trie?\n\n\n", \
TREE_NODES, TREE_BITS
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment