Flex

xiaoxiao2021-03-06  41

In 2001, he went to the work of C Master Andrei Alexandrescu:

"A policy-based basic_string us". Flex_string is essential. Later, read "Modern C Design", it is shocking, just as the Jet's translation says: "Let me look down, caught in Pensive ... and ... ... 惚." Loki library is like a treasure ... ...

Unfortunately, after downloading the source code for flex_string at the time, he was tested, and there were several obvious big bugs. It was even when it was more mistaken ...

This year, this year, the reason is that the colleague asking: He has a data structure that needs to use a large amount of lead-long character string to Key, but std :: string is a waste of space, const char * is not safe. Use, in addition to writing a Class, there is any other good way? This suddenly remembered the smallstringopt of flex_string, which is simply a custom-made solution, so find it.

The address of Code Snippets, found that flex_string has changed new version this year, and it is jealous. In particular, the author's sentence: "Harmut Kaizer Reported That SIMPLY DROPPING IN

Flex_string in the Wave Boost Preprocessor Improved ITS Speed ​​By 5-10%, Depending On Input. "Some people have done a white mouse, what should I do this time? So download compilation test ...

See all kinds of Storage, let me think of another thing: some programmers tell me that his project requires a lot of unordered strings as Key, just as a read-only string, no need anything Change, therefore, several pointers of std :: string become "more", in other words, he only wants a "save" and "safe" const char *. In fact, personal thinkingopt , 3> is enough, but others insist on "I like", what is the way? So I simply make a slimstringStorage for flex_string.

#include

template > class SlimStringStorage {// The "public" below exists because MSVC can not do template typedefspublic: static const E emptyString_; typedef typename A :: size_type size_type;

PRIVATE: E * PDATA_;

void init (size_type size) {if (pdata_! = & emptystring_) free (pdata_); if (size == 0) PDATA_ = const_cast (& emptystring_); else {pdata_ = static_cast (malloc (Sizeof (E) size * sizeof (e))))))); if (! PData_) throw std :: bad_alloc (); pdata_ [size] = E ();}} public: typedef e value_type; typef e * iperator; typedef const E * const_iterator; typedef a allocator_type;

SlimStringStorage (const SlimStringStorage & rhs) {pData_ = const_cast (& emptyString_); const size_type sz = rhs.size (); Init (sz); if (sz) flex_string_details :: pod_copy (rhs.begin (), rhs. Begin () SZ, Begin ());

SlimstringStorage (const slimstringstorage & s, flex_string_details :: shallow): PDATA_ (S.PDATA_) {}

SlimstringStorage (const A &) {pData_ = const_cast (& emptystring_);

SLIMSTRINGSTORAGE (Const E * S, SIZE_TYPE LEN, Const A &) {PDATA_ = const_cast (& emptystring_); init (len); flex_string_details :: POD_COPY (S, S, S, S LEN, Begin ());}

SLIMSTRINGSTORAGE (SIZE_TYPE LEN, E C, Const A &) {PDATA_ = const_cast (& Emptystring_); Init (LEN); flex_string_details :: pod_fill (begin (), begin () len, c);}

SlimStringStorage & operator = (const SlimStringStorage & rhs) {const size_type sz = rhs.size (); reserve (sz); if (sz) {flex_string_details :: pod_copy (& * rhs.begin (), & * (rhs.begin () SZ), begin ()); PDATA_ [SZ] = E ();} return * this;}

~ SlimstringStorage () {if (pdata_! = & Emptystring_) free (pdata_);}

Iterator begin () {return pdata_;}

Const_iterator begin () const {return pdata_;}

Iterator end () {return pData_ size ();

Const_iterator end () const {return pdata_ size ();} size_type size () const;

SIZE_TYPE MAX_SIZE () const {return size_t (-1) / sizeof (e) - sizeof (e *) - 1;}

SIZE_TYPE CAPACITY () Const {Return Size ();

Void Reserve (SIZE_TYPE RES_ARG) {IF (PDATA_ == & Emptystring_ || res_arg == 0) {INIT (RES_ARG); if (res_arg) * PDATA_ = E ();} else {const size_type sz = size (); if (); IF RES_ARG> SZ) {void * p = realloc (PDATA_, SIZEOF (E) RES_ARG * SIZEOF (E)); if (! p) throw std :: Bad_alloc ();

IF (p! = pdata_) {pData_ = static_cast (p); PDATA_ [SZ] = E ();} // if (p! = pdata_) PDATA_ [RES_ARG] = E ();}}}

Void append (const e * s) {const size_type szorg = size (); const size_type needededcapacity = szorg sz;

Const itrator b = begin (); static st: less_equal le; if (le (b, s) && le (s, pdata_ szorg)) {// aliased const size_type offset = s - b; Reserve (needededcapacity); s = begin () offset;} // if (le (b, s) && le (s, pdata_ szorg)) Else Reserve (neededcapacity); flex_string_details :: POD_COPY (S, S SZ , PDATA_ SZORG);

template void append (InputIterator b, InputIterator e) {const size_type szOrg = size (); const size_type neededCapacity = szOrg std :: distance (b, e); reserve (neededCapacity); for (E * p = PDATA_ SZORG; B! = E; B, P) * p = * b;}

Void Resize (SIZE_TYPE NEWSIZE, E FILL) {const size_type szorg = size (); const Int delta = int (newsize - szorg); if (delta == 0) Return;

Reserve (newsize); if (Delta> 0) {E * E = PDATA_ SZORG; flex_string_details :: POD_FILL (E, E DELTA, FILL);} // if (Delta> 0) Else if (newsize) PDATA_ [ Newsize] = e ();} void swap (slimstringstorage & r Hs) {std :: swap (pdata_, rhs.pdata_);

Const e * c_str () const {return pdata_;}

Const E * DATA () const {return pdata_;}

A get_allocator () const {returnon a ();}};

Template TypeName SlimstringStorage :: Size_Type SlimstringStorage :: Size () const {register const E * p = pdata_; for (;; * p; ); Return static_cast (p - pdata_);

Template Const e SlimstringStorage :: Emptystring_ = E ();

In fact, the principle is also very simple, the code of the Copy SimpleStringStorage, only one pointer is.

Finally, use flex_string test program testing, not passing ... Later, String Result (Random (0, MaxSize), '/ 0'); then becomes 0 when result.size () is obtained. Oh, that's of course, less a pointer points to the string end, only by looking for '/ 0', of course, size is incorrect, so few test programs:

String Result (Random (0, MaxSize), '/ 0'); INT i = 0; for (; i! = Result.size (); i)

Change to:

Size_t nsize = random (0, maxsize); String Result (nsize, '/ 0'); int i = 0; for (; i! = nsize; i) test passed. However, it is necessary to pay attention to it, using the meaning of SlimstringStorage's Flex_String's resize and ordinary String is different, but it doesn't matter.

Another thing I don't think is flex_string why not:

Template

Flex_string (const flex_string & str, size_type pos, size_type n = npos, const A & a = a ());

Template

Flex_string (const st: zic_string & str, size_type pos, size_type n = npos, const A & a = a ()); Template

Flex_string & operator = (const flex_string & str); Template

Flex_string & operator = (const st: Basic_String & STR);

The functions such as STD:: String and different storage flex_string can be mutually used up? The master may have a master's view, if you have time, add it slowly.

转载请注明原文地址:https://www.9cbs.com/read-51343.html

New Post(0)