There are some sturct arrays (or struct vectors), such as:
struct S1_t
{
double keyField ;
..// other fields
}
S1_t s1[100];
std::vector<S1_t> vecS1;
I need to find the index of the item in array "s1" or vector "vecS1"
which
has the minimal value in field "keyField".
Some codes could be:
//----------------------------------------------
double minvalue = s1[0];
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
....
{
if (s1[i].keyField < minvalue )
{
minvalue =s1[i].keyField;
index = i;
}
}
//----------------------------------------------
However, since there are many such arrays(vectors) with different
struct type
(so, with different "field" name)
How can I define a function (or MACRO?) to get the index
of the minumal item (by comparing the the value of a key field)?
such as MIN(struct_array_variable, field_name)
e.g.
index = MIN(s1, keyField);
to get the index of array "s1" with a minimal value of "keyField".
And ,
index = MIN(s2,f2) get that of "s2" (defined as follows:)
struct s2_t
{
int f2;
// other fields
}
s2_t s2[100]
A similar function is FIND(struct_array, field, value)
to find the index from array "struct_array", where
struct_array[index].field == value;
I think that the sticking point is that how to pass the field name
as a parameter? isn't it?
Could anyone help me?
Thank you very much! 17 2932
Jellicle wrote: There are some sturct arrays (or struct vectors), such as:
struct S1_t { double keyField ;
..// other fields }
S1_t s1[100]; std::vector<S1_t> vecS1; I need to find the index of the item in array "s1" or vector "vecS1" which has the minimal value in field "keyField".
Some codes could be: //----------------------------------------------
double minvalue = s1[0];
You mean
double minvalue = s1[0].keyField;
??
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
You mean
for (int i=1; i< ...
??
... { if (s1[i].keyField < minvalue ) { minvalue =s1[i].keyField; index = i; } } //----------------------------------------------
However, since there are many such arrays(vectors) with different struct type (so, with different "field" name)
How can I define a function (or MACRO?) to get the index of the minumal item (by comparing the the value of a key field)?
such as MIN(struct_array_variable, field_name)
e.g.
index = MIN(s1, keyField);
to get the index of array "s1" with a minimal value of "keyField".
And ,
index = MIN(s2,f2) get that of "s2" (defined as follows:)
struct s2_t { int f2;
// other fields
}
s2_t s2[100]
A similar function is FIND(struct_array, field, value) to find the index from array "struct_array", where
struct_array[index].field == value; I think that the sticking point is that how to pass the field name as a parameter? isn't it?
No, it isn't. The sticking point is to learn about pointers to
members and how they are used.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
you can get the offset of a field f in a struct s using the following
well-known trick:
#define OFFSET(s,f) &((struct s *) 0)->f
Once you have the offset, it becomes straightforward to solve your problem.
-Shimin
Jellicle wrote: There are some sturct arrays (or struct vectors), such as:
struct S1_t { double keyField ;
..// other fields }
S1_t s1[100]; std::vector<S1_t> vecS1; I need to find the index of the item in array "s1" or vector "vecS1" which has the minimal value in field "keyField".
Some codes could be: //----------------------------------------------
double minvalue = s1[0]; for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++) ... { if (s1[i].keyField < minvalue ) { minvalue =s1[i].keyField; index = i; } } //----------------------------------------------
However, since there are many such arrays(vectors) with different struct type (so, with different "field" name)
How can I define a function (or MACRO?) to get the index of the minumal item (by comparing the the value of a key field)?
such as MIN(struct_array_variable, field_name)
e.g.
index = MIN(s1, keyField);
to get the index of array "s1" with a minimal value of "keyField".
And ,
index = MIN(s2,f2) get that of "s2" (defined as follows:)
struct s2_t { int f2;
// other fields
}
s2_t s2[100]
A similar function is FIND(struct_array, field, value) to find the index from array "struct_array", where
struct_array[index].field == value; I think that the sticking point is that how to pass the field name as a parameter? isn't it?
Could anyone help me?
Thank you very much!
Victor Bazarov wrote: Jellicle wrote: Some codes could be: //----------------------------------------------
double minvalue = s1[0];
You mean
double minvalue = s1[0].keyField;
??
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
You mean
for (int i=1; i< ...
??
You are right exactly :-).
(and I should check if vecS1[0] exists in a vector :-) )
But what I puzzled is that how to handle the various types of
structs and fields in different arrays or vectors.
Shimin wrote: you can get the offset of a field f in a struct s using the following well-known trick:
Please don't top-post. See item four in the FAQ below:
<http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4>
Brian
Shimin wrote: you can get the offset of a field f in a struct s using the following well-known trick:
#define OFFSET(s,f) &((struct s *) 0)->f
Once you have the offset, it becomes straightforward to solve your problem.
-Shimin
First, don't top-post. It is considered rude. Second, don't use this
trick unless you must. (Generally, if you must, it means your design is
flawed.)
A better solution would use a function to extract the proper key.
Something like:
struct S1 { int key1; /*...*/ };
struct S2 { int key2; /*...*/ };
int GetKey( const S1& s ) { return s.key1; }
int GetKey( const S2& s ) { return s.key2; }
template<class T>
int MinKey( const vector<T>& v )
{
if( v.size() == 0 ) return -1;
int min = GetKey( v[0] );
for( vector<T>::const_iterator i = v.begin()+1; i != v.end(); ++i )
{
if( GetKey( *i ) < min ) min = GetKey( *i );
}
return min;
}
If the keys are also different types, you could still do it, but it
would have to be a little fancier.
Cheers! --M
Shimin 写道: you can get the offset of a field f in a struct s using the following well-known trick:
#define OFFSET(s,f) &((struct s *) 0)->f
Once you have the offset, it becomes straightforward to solve your problem.
-Shimin
Thank you!
Would you explain it in detail?
1)how to implement something like :
if (s1[i].keyField < minvalue )
2) Is it possible to return a value, so
I can write a compact and beautiful statement in my codes:
index = MIN(s1, field);
But I am afrad that a macro can not return a value.
Jellicle wrote: There are some sturct arrays (or struct vectors), such as:
struct S1_t { double keyField ;
..// other fields }
S1_t s1[100]; std::vector<S1_t> vecS1; I need to find the index of the item in array "s1" or vector "vecS1" which has the minimal value in field "keyField".
Some codes could be: //----------------------------------------------
double minvalue = s1[0]; for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++) ... { if (s1[i].keyField < minvalue ) { minvalue =s1[i].keyField; index = i; } } //----------------------------------------------
However, since there are many such arrays(vectors) with different struct type (so, with different "field" name)
How can I define a function (or MACRO?) to get the index of the minumal item (by comparing the the value of a key field)?
such as MIN(struct_array_variable, field_name)
e.g.
index = MIN(s1, keyField);
to get the index of array "s1" with a minimal value of "keyField".
A STL style solution using iterators would be:
#include <iterator>
template<class Iterator, typename T> Iterator minfield(Iterator start,
const Iterator &end, T std::iterator_traits<Iterator>::value_type::*p)
{
T acc = (*start).*p;
Iterator min_i(start);
++start;
while(start != end)
{
const T &r = (*start).*p;
if(r < acc)
{
acc = r;
min_i = start;
}
++start;
}
return min_i;
}
Usage would be:
index = minfield(s1, s1 + 100, &S1_t::keyfield) - s1;
or
index = minfield(vecS1.begin(), vecS1.end(), &S1_t::keyfield) -
vecS1.begin();
Note that the function assumes that there is at least one value in the range
[start, end).
Jellicle wrote: Shimin 写道:
you can get the offset of a field f in a struct s using the following well-known trick:
#define OFFSET(s,f) &((struct s *) 0)->f
Once you have the offset, it becomes straightforward to solve your problem.
-Shimin
Thank you!
Would you explain it in detail?
To repeat from my post above, this trick should be avoided. See my post
and Markus Schoder's for two better options.
1)how to implement something like : if (s1[i].keyField < minvalue )
2) Is it possible to return a value, so I can write a compact and beautiful statement in my codes:
index = MIN(s1, field);
But I am afrad that a macro can not return a value.
Technically, a macro doesn't return anything. Macros are not functions
(despite the similar looking syntax); they are text substitutions. If
the text you substitute evaluates to a value, then it can be assigned
to some variable like you want to here. If it does not, then it cannot
be. For instance:
#define A 42
#define B { cout << "Hello"; }
int main()
{
int val1 = A; // Ok: becomes "int val1 = 42;"
int val2 = B; // Error: becomes "int val2 = { cout << "Hello"; };"
}
However, macros should be avoided when possible. See this FAQ and its
references for reasons why: http://www.parashift.com/c++-faq-lit...s.html#faq-9.5
Cheers! --M
Markus Schoder wrote: A STL style solution using iterators would be:
#include <iterator>
template<class Iterator, typename T> Iterator minfield(Iterator start, const Iterator &end, T std::iterator_traits<Iterator>::value_type::*p) { T acc = (*start).*p; Iterator min_i(start); ++start; while(start != end) { const T &r = (*start).*p; if(r < acc) { acc = r; min_i = start; } ++start; } return min_i; }
Usage would be:
index = minfield(s1, s1 + 100, &S1_t::keyfield) - s1;
or
index = minfield(vecS1.begin(), vecS1.end(), &S1_t::keyfield) - vecS1.begin();
Note that the function assumes that there is at least one value in the range [start, end).
Thank you and everyone!
But I cannot compile the codes successfully in Visual C++ 6.0.
It said that
"error C2653: 'value_type' : is not a class or namespace name"
on this line:
const Iterator &end, T
std::iterator_traits<Iterator>::value_type::*p)
if I remove "::" between "value_type" and "*p", it says:
"error C2143: syntax error : missing ',' before '*' "
Since I don't understand this code line exactly, I don't know how to
correct it.
Would you help me?
Thank you!
Jellicle wrote: But I cannot compile the codes successfully in Visual C++ 6.0.
You probably need a newer compiler.
Markus Schoder wrote: Jellicle wrote: But I cannot compile the codes successfully in Visual C++ 6.0.
You probably need a newer compiler.
Try this (I didn't test it, but it compiles :-) ). I think it should
work with VC++ 6, and it works with keys of different types and
different names:
#include <vector>
#include <cassert>
using namespace std;
template<class Iterator, typename key_type, typename T>
Iterator minfield(
Iterator start,
const Iterator &end,
key_type T::*p)
{
key_type acc = (*start).*p;
Iterator min_i(start);
++start;
while(start != end)
{
const key_type &r = (*start).*p;
if(r < acc)
{
acc = r;
min_i = start;
}
++start;
}
return min_i;
}
struct S1
{
typedef int key_type;
key_type key1;
S1( key_type key ) : key1(key) {}
};
struct S2
{
typedef double key_type;
key_type key2;
S2( key_type key ) : key2(key) {}
};
int main()
{
std::vector<S1> v1;
v1.push_back( S1(1) );
v1.push_back( S1(5) );
v1.push_back( S1(-10) );
v1.push_back( S1(3) );
vector<S1>::const_iterator m1 = minfield(
v1.begin(), v1.end(), &S1::key1 );
assert( m1->key1 == -10 );
std::vector<S2> v2;
v2.push_back( S2(1.1) );
v2.push_back( S2(5.1) );
v2.push_back( S2(-1.1) );
v2.push_back( S2(3.1) );
vector<S2>::const_iterator m2 = minfield(
v2.begin(), v2.end(), &S2::key2 );
assert( m2->key2 == -1.1 );
return 0;
}
Cheers! --M
mlimber 写道: Jellicle wrote: Shimin 写道:
you can get the offset of a field f in a struct s using the following well-known trick:
#define OFFSET(s,f) &((struct s *) 0)->f
Once you have the offset, it becomes straightforward to solve your problem.
-Shimin
Thank you!
Would you explain it in detail?
To repeat from my post above, this trick should be avoided. See my post and Markus Schoder's for two better options.
1)how to implement something like : if (s1[i].keyField < minvalue )
2) Is it possible to return a value, so I can write a compact and beautiful statement in my codes:
index = MIN(s1, field);
But I am afrad that a macro can not return a value.
Technically, a macro doesn't return anything. Macros are not functions (despite the similar looking syntax); they are text substitutions. If the text you substitute evaluates to a value, then it can be assigned to some variable like you want to here. If it does not, then it cannot be. For instance:
#define A 42 #define B { cout << "Hello"; }
int main() { int val1 = A; // Ok: becomes "int val1 = 42;" int val2 = B; // Error: becomes "int val2 = { cout << "Hello"; };" }
However, macros should be avoided when possible. See this FAQ and its references for reasons why:
http://www.parashift.com/c++-faq-lit...s.html#faq-9.5
Thank you!
And I found the url link you gave was quite useful for me:)
I think that the (only?) good feature of a macro is that it works on
"compiling time".
so I can replace the codes ( not the data). It maybe save some similar
codes.
for example,
#define FIELDNAME( field) field
mystruct.FIELDNAME(myfield)
==> mystruct.myfield
Cheers! --M
mlimber 写道: Markus Schoder wrote: Jellicle wrote: But I cannot compile the codes successfully in Visual C++ 6.0.
You probably need a newer compiler.
Try this (I didn't test it, but it compiles :-) ). I think it should work with VC++ 6, and it works with keys of different types and different names:
#include <vector> #include <cassert>
using namespace std;
template<class Iterator, typename key_type, typename T> Iterator minfield( Iterator start, const Iterator &end, key_type T::*p) { key_type acc = (*start).*p; Iterator min_i(start); ++start; while(start != end) { const key_type &r = (*start).*p; if(r < acc) { acc = r; min_i = start; } ++start; } return min_i; }
struct S1 { typedef int key_type; key_type key1; S1( key_type key ) : key1(key) {} };
struct S2 { typedef double key_type; key_type key2; S2( key_type key ) : key2(key) {} };
int main() { std::vector<S1> v1; v1.push_back( S1(1) ); v1.push_back( S1(5) ); v1.push_back( S1(-10) ); v1.push_back( S1(3) );
vector<S1>::const_iterator m1 = minfield( v1.begin(), v1.end(), &S1::key1 ); assert( m1->key1 == -10 );
std::vector<S2> v2; v2.push_back( S2(1.1) ); v2.push_back( S2(5.1) ); v2.push_back( S2(-1.1) ); v2.push_back( S2(3.1) );
vector<S2>::const_iterator m2 = minfield( v2.begin(), v2.end(), &S2::key2 ); assert( m2->key2 == -1.1 );
return 0; }
Cheers! --M
Thank you, mlimber. I am really grateful for you kind help!
Yes, it works well in VC6 :)
However, my question is that the structs were defined by other people,
and were used
somewhere else. So I cannot redefine them.
Jellicle wrote: mlimber 写道:
Markus Schoder wrote: Jellicle wrote: > But I cannot compile the codes successfully in Visual C++ 6.0.
You probably need a newer compiler.
Try this (I didn't test it, but it compiles :-) ). I think it should work with VC++ 6, and it works with keys of different types and different names:
#include <vector> #include <cassert>
using namespace std;
template<class Iterator, typename key_type, typename T> Iterator minfield( Iterator start, const Iterator &end, key_type T::*p) { key_type acc = (*start).*p; Iterator min_i(start); ++start; while(start != end) { const key_type &r = (*start).*p; if(r < acc) { acc = r; min_i = start; } ++start; } return min_i; }
struct S1 { typedef int key_type; key_type key1; S1( key_type key ) : key1(key) {} };
struct S2 { typedef double key_type; key_type key2; S2( key_type key ) : key2(key) {} };
int main() { std::vector<S1> v1; v1.push_back( S1(1) ); v1.push_back( S1(5) ); v1.push_back( S1(-10) ); v1.push_back( S1(3) );
vector<S1>::const_iterator m1 = minfield( v1.begin(), v1.end(), &S1::key1 ); assert( m1->key1 == -10 );
std::vector<S2> v2; v2.push_back( S2(1.1) ); v2.push_back( S2(5.1) ); v2.push_back( S2(-1.1) ); v2.push_back( S2(3.1) );
vector<S2>::const_iterator m2 = minfield( v2.begin(), v2.end(), &S2::key2 ); assert( m2->key2 == -1.1 );
return 0; }
Cheers! --M
Thank you, mlimber. I am really grateful for you kind help!
Yes, it works well in VC6 :)
However, my question is that the structs were defined by other people, and were used somewhere else. So I cannot redefine them.
There should be no need to alter the structs (I had initially added the
key_type to them but realized I didn't need to). If the structs looked
like this, it would work the same:
struct S1
{
int key1;
// ... whatever else
};
struct S2
{
double key2;
// ... whatever else
};
Cheers! --M
Jellicle wrote: I think that the (only?) good feature of a macro is that it works on "compiling time".
Macros are occasionally necessary. See this FAQ: http://www.parashift.com/c++-faq-lit....html#faq-6.16
so I can replace the codes ( not the data). It maybe save some similar codes.
for example,
#define FIELDNAME( field) field
mystruct.FIELDNAME(myfield) ==> mystruct.myfield
I don't see how this example buys you anything, and thus I don't think
it is a good use of macros.
Cheers! --M
mlimber 写道: Jellicle wrote: mlimber 写道:
Markus Schoder wrote: > Jellicle wrote: > > But I cannot compile the codes successfully in Visual C++ 6.0. > > You probably need a newer compiler.
Try this (I didn't test it, but it compiles :-) ). I think it should work with VC++ 6, and it works with keys of different types and different names:
#include <vector> #include <cassert>
using namespace std;
template<class Iterator, typename key_type, typename T> Iterator minfield( Iterator start, const Iterator &end, key_type T::*p) { key_type acc = (*start).*p; Iterator min_i(start); ++start; while(start != end) { const key_type &r = (*start).*p; if(r < acc) { acc = r; min_i = start; } ++start; } return min_i; }
struct S1 { typedef int key_type; key_type key1; S1( key_type key ) : key1(key) {} };
struct S2 { typedef double key_type; key_type key2; S2( key_type key ) : key2(key) {} };
int main() { std::vector<S1> v1; v1.push_back( S1(1) ); v1.push_back( S1(5) ); v1.push_back( S1(-10) ); v1.push_back( S1(3) );
vector<S1>::const_iterator m1 = minfield( v1.begin(), v1.end(), &S1::key1 ); assert( m1->key1 == -10 );
std::vector<S2> v2; v2.push_back( S2(1.1) ); v2.push_back( S2(5.1) ); v2.push_back( S2(-1.1) ); v2.push_back( S2(3.1) );
vector<S2>::const_iterator m2 = minfield( v2.begin(), v2.end(), &S2::key2 ); assert( m2->key2 == -1.1 );
return 0; }
Cheers! --M
Thank you, mlimber. I am really grateful for you kind help!
Yes, it works well in VC6 :)
However, my question is that the structs were defined by other people, and were used somewhere else. So I cannot redefine them.
There should be no need to alter the structs (I had initially added the key_type to them but realized I didn't need to). If the structs looked like this, it would work the same:
struct S1 { int key1; // ... whatever else };
struct S2 { double key2; // ... whatever else };
Yes! It works! Thank you:)
And do you think that at least I can save a little time/space if I use
a macro as this :-)
// for vector of struct
#define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) -
vs.begin())
// for array of struct
#define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
I have test these as follows
#define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) -
vs.begin())
#define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
main()
{
score_t scores[3]={100,93, 71, 70,59,83, 77,99,88};
int d2 = MINFIELD2(scores, 3, score_t::mathematics);
int d3 = MINFIELD2(scores, 3, score_t::mathematics) * 6;
int d4 = 8 * MINFIELD2(scores, 3, score_t::mathematics);
std::vector<goods_t> gg;
goods_t g;
g.price = 122.1; g.amount=100;
gg.push_back(g);
g.price = 322.2; g.amount=120;
gg.push_back(g);
g.price = 1012.4; g.amount=12;
gg.push_back(g);
g.price = 102.3; g.amount=110;
gg.push_back(g);
int i5 = MINFIELD(gg, goods_t::price);
int i6= 5*MINFIELD(gg, goods_t::price);
int i7 = MINFIELD(gg, goods_t::price) * 6;
return 0;
}
Cheers! --M
Jellicle 写道: mlimber 写道:
Jellicle wrote: mlimber 写道:
> Markus Schoder wrote: > > Jellicle wrote: > > > But I cannot compile the codes successfully in Visual C++ 6.0. > > > > You probably need a newer compiler. > > Try this (I didn't test it, but it compiles :-) ). I think it should > work with VC++ 6, and it works with keys of different types and > different names: > > #include <vector> > #include <cassert> > > using namespace std; > > template<class Iterator, typename key_type, typename T> > Iterator minfield( > Iterator start, > const Iterator &end, > key_type T::*p) > { > key_type acc = (*start).*p; > Iterator min_i(start); > ++start; > while(start != end) > { > const key_type &r = (*start).*p; > if(r < acc) > { > acc = r; > min_i = start; > } > ++start; > } > return min_i; > } > > struct S1 > { > typedef int key_type; > key_type key1; > S1( key_type key ) : key1(key) {} > }; > > struct S2 > { > typedef double key_type; > key_type key2; > S2( key_type key ) : key2(key) {} > }; > > int main() > { > std::vector<S1> v1; > v1.push_back( S1(1) ); > v1.push_back( S1(5) ); > v1.push_back( S1(-10) ); > v1.push_back( S1(3) ); > > vector<S1>::const_iterator m1 = minfield( > v1.begin(), v1.end(), &S1::key1 ); > assert( m1->key1 == -10 ); > > std::vector<S2> v2; > v2.push_back( S2(1.1) ); > v2.push_back( S2(5.1) ); > v2.push_back( S2(-1.1) ); > v2.push_back( S2(3.1) ); > > vector<S2>::const_iterator m2 = minfield( > v2.begin(), v2.end(), &S2::key2 ); > assert( m2->key2 == -1.1 ); > > return 0; > } > > Cheers! --M
Thank you, mlimber. I am really grateful for you kind help!
Yes, it works well in VC6 :)
However, my question is that the structs were defined by other people, and were used somewhere else. So I cannot redefine them. There should be no need to alter the structs (I had initially added the key_type to them but realized I didn't need to). If the structs looked like this, it would work the same:
struct S1 { int key1; // ... whatever else };
struct S2 { double key2; // ... whatever else };
Yes! It works! Thank you:)
And do you think that at least I can save a little time/space if I use a macro as this :-)
// for vector of struct #define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) - vs.begin())
// for array of struct #define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
I have test these as follows
#define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) - vs.begin()) #define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
main() {
score_t scores[3]={100,93, 71, 70,59,83, 77,99,88};
int d2 = MINFIELD2(scores, 3, score_t::mathematics); int d3 = MINFIELD2(scores, 3, score_t::mathematics) * 6; int d4 = 8 * MINFIELD2(scores, 3, score_t::mathematics);
std::vector<goods_t> gg; goods_t g;
g.price = 122.1; g.amount=100; gg.push_back(g);
g.price = 322.2; g.amount=120; gg.push_back(g);
g.price = 1012.4; g.amount=12; gg.push_back(g);
g.price = 102.3; g.amount=110; gg.push_back(g); int i5 = MINFIELD(gg, goods_t::price); int i6= 5*MINFIELD(gg, goods_t::price); int i7 = MINFIELD(gg, goods_t::price) * 6;
return 0; }
struct score_t
{
int mathematics;
int physics;
int chemistry;
};
struct goods_t
{
double price;
int amount;
}; Cheers! --M This discussion thread is closed Replies have been disabled for this discussion. Similar topics
110 posts
views
Thread by Mr A |
last post: by
|
2 posts
views
Thread by Tony Johansson |
last post: by
|
5 posts
views
Thread by Don Seckler |
last post: by
|
6 posts
views
Thread by yezi |
last post: by
|
3 posts
views
Thread by Brad McMillan |
last post: by
|
3 posts
views
Thread by Ronald S. Cook |
last post: by
|
12 posts
views
Thread by Fred |
last post: by
|
7 posts
views
Thread by p.lavarre |
last post: by
|
4 posts
views
Thread by S. |
last post: by
| | | | | | | | | | |