Construction From vector<char> ?

David Fang fang at csl.cornell.edu
Wed Aug 13 11:55:49 CEST 2008


On Tue, 12 Aug 2008, Marc Glisse wrote:
> On Tue, 12 Aug 2008, Robert Evans wrote:
>> I am trying to migrate  some  C++ code based on STL vector<char>  - based
>> arrays to mpz_class.  Is there an efficient way to construct  an
>> mpz_class object from a vector<char> without explicitly iterating over
>> the vector?  I could not find  a  constructor  based on an STL vector,
>> nor could I find a string constructor based  on vector<char> (which I
>> could then feed into mpz_class(const string&) ).
>
> It all depends on what the vector<char> is supposed to represent. If it
> was used in place of a string (as a list of the ascii representations of
> the digits of a base 10 representation of the number), you can easily
> create a string from your vector v, with:
>
> string s(v.begin(),v.end());
> or with:
> string s(&v[0],v.size());
> (the second one was not legal in early C++)


Hi all,

Would anyone object to adding an iterator constructor (similar to 
std::string taking a pair of iterators)?  I'll just describe the idea 
below, I don't have time to provide a full patch at the moment.

First, provide a generic interface function:

/**
 	\param p pointer to mpz structure to set
 	\param b beginning of character sequence
 	\param e one-past-last character iterator (end)
  */
template <typename Iter>
// inline
int
mpz_init_set_iter(mpz_ptr p, Iter b, Iter e) {
 	return __mpz_init_set_iter_dispatch(p,b,e,
 		typename std::iterator_traits<Iter>::iterator_category());
 	// dispatcher calls an efficient function for random-access
 	// iterators, such as char*, vector<char>::iterator,
 	// string::iterator, ...
 	// and some less efficient fallback routine for other iterators
}

// 
template <typename Iter>
int
__mpz_init_set_iter_dispatch(mpz_ptr p, Iter b, Iter e,
 		std::random_access_iterator_tag) {
 	// this example only works for value_type=char...
 	return mpz_init_set_str(p, &*b, std::distance(b,e));
}

// mpz_class actually refers to __gmp_expr<__gmpz_value, __gmpz_value>
class mpz_class {
...
/**
 	Constructor takes any pair of iterators to be treated as
 	bounds of a string or substring to be interpreted.
  */
template <class Iter>
mpz_class(Iter b, Iter e) {
 	mpz_init_set_iter(mp, b, e);
 	// dispatcher chooses appropriate call at compile-time
}

};


One downside to this is that use of iterator traits requires the 
<iterator> header, more baggage to preprocess.  This also relies on the 
compiler to inline away the dispatched function calls, and just forward 
arguments to the innermost call.

Is such an interface worthwhile?


Fang


David Fang
Computer Systems Laboratory
Electrical & Computer Engineering
Cornell University
http://www.csl.cornell.edu/~fang/
 	-- (2400 baud? Netscape 3.0?? lynx??? No problem!)


More information about the gmp-discuss mailing list