| Thread overview | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 19, 2010 main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Hi there,
I'm converting the following C++ function to D:
void negate ()
{
const std::size_t max_chars_ = sizeof (CharT) == 1 ?
num_chars : num_wchar_ts;
CharT curr_char_ = sizeof (CharT) == 1 ? -128 : 0;
string temp_;
const CharT *curr_ = _charset.c_str ();
const CharT *chars_end_ = curr_ + _charset.size ();
_negated = !_negated;
temp_.resize (max_chars_ - _charset.size ());
CharT *ptr_ = const_cast<CharT *> (temp_.c_str ());
std::size_t i_ = 0;
while (curr_ < chars_end_)
{
while (*curr_ > curr_char_)
{
*ptr_ = curr_char_;
++ptr_;
++curr_char_;
++i_;
}
++curr_char_;
++curr_;
++i_;
}
for (; i_ < max_chars_; ++i_)
{
*ptr_ = curr_char_;
++ptr_;
++curr_char_;
}
_charset = temp_;
}
Here's the complete source:
module main;
import std.algorithm;
import std.string;
template regex(StringT)
{
struct basic_string_token
{
bool _negated = false;
StringT _charset;
typedef typeof(StringT.init[0]) CharT;
enum size_t MAX_CHARS = CharT.max + 1;
this(const bool negated_, ref StringT charset_)
{
_negated = negated_;
_charset = charset_;
}
void remove_duplicates()
{
_charset.sort;
_charset = squeeze(_charset);
}
void normalise()
{
if (_charset.length == MAX_CHARS)
{
_negated = !_negated;
_charset.clear();
}
else if (_charset.length > MAX_CHARS / 2)
{
negate();
}
}
void negate()
{
CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0;
StringT temp_;
size_t curr_ = 0;
size_t end_ = _charset.length;
size_t i_ = 0;
_negated = !_negated;
temp_.length = MAX_CHARS - end_;
while (curr_ < end_)
{
while (_charset[curr_] > curr_char_)
{
temp_[i_] = curr_char_;
++curr_char_;
++i_;
}
++curr_char_;
++curr_;
++i_;
}
for (; i_ < MAX_CHARS; ++i_)
{
temp_ ~= curr_char_;
++curr_char_;
}
_charset = temp_;
}
};
}
int main(char[][]argv)
{
regex!(string).basic_string_token token_;
token_._charset = "cccbba";
token_.remove_duplicates();
token_.negate();
return 0;
}
Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't mutable'? Can I use pointers instead like the C++ code? What's the best approach for maximum efficiency in D (pointers would make the conversion easier to, I guess).
Thanks,
Ben
| ||||
June 19, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ben Hanson | On 06/19/2010 12:30 PM, Ben Hanson wrote: > Hi there, > > I'm converting the following C++ function to D: > > void negate () > { > const std::size_t max_chars_ = sizeof (CharT) == 1 ? > num_chars : num_wchar_ts; > CharT curr_char_ = sizeof (CharT) == 1 ? -128 : 0; > string temp_; > const CharT *curr_ = _charset.c_str (); > const CharT *chars_end_ = curr_ + _charset.size (); > > _negated = !_negated; > temp_.resize (max_chars_ - _charset.size ()); > > CharT *ptr_ = const_cast<CharT *> (temp_.c_str ()); > std::size_t i_ = 0; > > while (curr_< chars_end_) > { > while (*curr_> curr_char_) > { > *ptr_ = curr_char_; > ++ptr_; > ++curr_char_; > ++i_; > } > > ++curr_char_; > ++curr_; > ++i_; > } > > for (; i_< max_chars_; ++i_) > { > *ptr_ = curr_char_; > ++ptr_; > ++curr_char_; > } > > _charset = temp_; > } > > Here's the complete source: > > module main; > > import std.algorithm; > import std.string; > > template regex(StringT) > { > struct basic_string_token > { > bool _negated = false; > StringT _charset; > typedef typeof(StringT.init[0]) CharT; > enum size_t MAX_CHARS = CharT.max + 1; > > this(const bool negated_, ref StringT charset_) > { > _negated = negated_; > _charset = charset_; > } > > void remove_duplicates() > { > _charset.sort; > _charset = squeeze(_charset); > } > > void normalise() > { > if (_charset.length == MAX_CHARS) > { > _negated = !_negated; > _charset.clear(); > } > else if (_charset.length> MAX_CHARS / 2) > { > negate(); > } > } > > void negate() > { > CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0; > StringT temp_; > size_t curr_ = 0; > size_t end_ = _charset.length; > size_t i_ = 0; > > _negated = !_negated; > temp_.length = MAX_CHARS - end_; > > while (curr_< end_) > { > while (_charset[curr_]> curr_char_) > { > temp_[i_] = curr_char_; > ++curr_char_; > ++i_; > } > > ++curr_char_; > ++curr_; > ++i_; > } > > for (; i_< MAX_CHARS; ++i_) > { > temp_ ~= curr_char_; > ++curr_char_; > } > > _charset = temp_; > } > }; > } > > int main(char[][]argv) > { > regex!(string).basic_string_token token_; > > token_._charset = "cccbba"; > token_.remove_duplicates(); > token_.negate(); > return 0; > } > > Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't > mutable'? Can I use pointers instead like the C++ code? What's the > best approach for maximum efficiency in D (pointers would make the > conversion easier to, I guess). > > Thanks, > > Ben because strings aren't mutable. char[]'s on the other hand are, so you could just change temp_'s type to import std.traits; Unqual!(typeof(StringT.init[0]))[] temp_; or something like that. | |||
June 19, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ben Hanson | On Sat, 19 Jun 2010 17:30:26 +0000 (UTC), Ben Hanson <Ben.Hanson@tfbplc.co.uk> wrote:
> Here's the complete source:
>
> module main;
>
> import std.algorithm;
> import std.string;
>
> template regex(StringT)
> {
> struct basic_string_token
> {
> bool _negated = false;
> StringT _charset;
> typedef typeof(StringT.init[0]) CharT;
> enum size_t MAX_CHARS = CharT.max + 1;
>
> this(const bool negated_, ref StringT charset_)
> {
> _negated = negated_;
> _charset = charset_;
> }
>
> void remove_duplicates()
> {
> _charset.sort;
> _charset = squeeze(_charset);
> }
>
> void normalise()
> {
> if (_charset.length == MAX_CHARS)
> {
> _negated = !_negated;
> _charset.clear();
> }
> else if (_charset.length > MAX_CHARS / 2)
> {
> negate();
> }
> }
>
> void negate()
> {
> CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0;
> StringT temp_;
> size_t curr_ = 0;
> size_t end_ = _charset.length;
> size_t i_ = 0;
>
> _negated = !_negated;
> temp_.length = MAX_CHARS - end_;
>
> while (curr_ < end_)
> {
> while (_charset[curr_] > curr_char_)
> {
> temp_[i_] = curr_char_;
> ++curr_char_;
> ++i_;
> }
>
> ++curr_char_;
> ++curr_;
> ++i_;
> }
>
> for (; i_ < MAX_CHARS; ++i_)
> {
> temp_ ~= curr_char_;
> ++curr_char_;
> }
>
> _charset = temp_;
> }
> };
> }
>
> int main(char[][]argv)
> {
> regex!(string).basic_string_token token_;
>
> token_._charset = "cccbba";
> token_.remove_duplicates();
> token_.negate();
> return 0;
> }
>
> Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't mutable'? Can I use pointers instead like the C++ code? What's the best approach for maximum efficiency in D (pointers would make the conversion easier to, I guess).
>
> Thanks,
>
> Ben
"string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward.
| |||
June 19, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ellery Newcomer | > because strings aren't mutable. char[]'s on the other hand are, so you
> could just change temp_'s type to
> import std.traits;
> Unqual!(typeof(StringT.init[0]))[] temp_;
> or something like that.
Thanks Ellery.
| |||
June 19, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Spahr-Summers | Hi Justin, == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s article > "string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward. Thanks for the clarification! Regards, Ben | |||
June 20, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Spahr-Summers | == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s > "string" is actually an alias for "immutable(char)[]" (and similarly for > the other string types), so its contents are not modifiable, though its > length can be adjusted and contents appended. If you need to be able to > modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward. I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing: _charset = temp_.idup; main.d(76): Error: cannot implicitly convert expression (_adDupT((& D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast (string)temp_)) of type immutable(CharT)[] to string | |||
June 20, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ben Hanson | Ben Hanson wrote: > == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s >> "string" is actually an alias for "immutable(char)[]" (and > similarly for >> the other string types), so its contents are not modifiable, though > its >> length can be adjusted and contents appended. If you need to be > able to >> modify the characters, just use char[] instead. You can then use the >> .idup property to get a string afterward. > > I'm converted temp_ to CharT[] as suggested, but the conversion back > to a string is failing: > > _charset = temp_.idup; > > main.d(76): Error: cannot implicitly convert expression (_adDupT((& > D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast > (string)temp_)) of type immutable(CharT)[] to string Would it work for you if the regex template took the character type instead of the string type? The relevant lines: template regex(CharT) { // ... alias CharT[] StringT; StringT _charset; enum size_t MAX_CHARS = CharT.max + 1; // ... _charset = squeeze(_charset.idup).dup; And then, in main: regex!(char).basic_string_token token_; Ali | |||
June 20, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ben Hanson | On 06/20/2010 07:01 AM, Ben Hanson wrote:
> == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s
>> "string" is actually an alias for "immutable(char)[]" (and
> similarly for
>> the other string types), so its contents are not modifiable, though
> its
>> length can be adjusted and contents appended. If you need to be
> able to
>> modify the characters, just use char[] instead. You can then use the
>> .idup property to get a string afterward.
>
> I'm converted temp_ to CharT[] as suggested, but the conversion back
> to a string is failing:
>
> _charset = temp_.idup;
>
> main.d(76): Error: cannot implicitly convert expression (_adDupT((&
> D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast
> (string)temp_)) of type immutable(CharT)[] to string
import std.conv;
...
_charset = to!(typeof(_charset))(temp_);
"to" converts strings of any width and mutability to strings of any width and mutability.
Andrei
| |||
June 20, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 06/20/2010 12:56 PM, Ali Çehreli wrote:
> Ben Hanson wrote:
>> == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s
>>> "string" is actually an alias for "immutable(char)[]" (and
>> similarly for
>>> the other string types), so its contents are not modifiable, though
>> its
>>> length can be adjusted and contents appended. If you need to be
>> able to
>>> modify the characters, just use char[] instead. You can then use the
>>> .idup property to get a string afterward.
>>
>> I'm converted temp_ to CharT[] as suggested, but the conversion back
>> to a string is failing:
>>
>> _charset = temp_.idup;
>>
>> main.d(76): Error: cannot implicitly convert expression (_adDupT((&
>> D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast
>>
>> (string)temp_)) of type immutable(CharT)[] to string
>
>
> Would it work for you if the regex template took the character type
> instead of the string type?
>
> The relevant lines:
>
> template regex(CharT)
> {
> // ...
> alias CharT[] StringT;
> StringT _charset;
> enum size_t MAX_CHARS = CharT.max + 1;
> // ...
> _charset = squeeze(_charset.idup).dup;
>
> And then, in main:
>
> regex!(char).basic_string_token token_;
>
> Ali
IMHO it's more general if the regexp took the string type as a parameter. This is because later that is easier generalizable to accepting a range that's different from an array.
My dream: to have a compile-time-generated regex engine that can operate on any input stream.
Andrei
| |||
June 20, 2010 Re: main.d(61): Error: temp_[i_] isn't mutable | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ben Hanson | On Sun, 20 Jun 2010 12:01:31 +0000 (UTC), Ben Hanson <Ben.Hanson@tfbplc.co.uk> wrote:
>
> == Quote from Justin Spahr-Summers (Justin.SpahrSummers@gmail.com)'s
> > "string" is actually an alias for "immutable(char)[]" (and
> similarly for
> > the other string types), so its contents are not modifiable, though
> its
> > length can be adjusted and contents appended. If you need to be
> able to
> > modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward.
>
> I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing:
>
> _charset = temp_.idup;
>
> main.d(76): Error: cannot implicitly convert expression (_adDupT((&
> D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast
> (string)temp_)) of type immutable(CharT)[] to string
Sorry I missed this on the first run through. Since you're using typedef to create your CharT type, it will create a type independent from all the others, meaning no implicit casts to or from it. "alias" is the equivalent to a C/C++ "typedef", and that should fix the compilation error.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply