- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/include/frost_utils_ctnr.h

Go to the documentation of this file.

    00001 // Warning : If you need to use this file, include frost_utils_types.h
    00002 #include <deque>
    00003 #include <vector>
    00004 #include <algorithm>
    00005
    00006 #include "frost_utils_range.h"
    00007 #include "frost_utils_pair.h"
    00008
    00009 namespace Frost
    00010 {
    00011     /// Base type : container (sequence)
    00012     /** This is a generic 1D container. It is implemented
    00013     *   by an std::deque for s_ctnr, and an std::vector for s_array.
    00014     */
    00015     template< class T, class C >
    00016     class s_ctnr_t
    00017     {
    00018     public :
    00019
    00020         typedef T                          ValueType;
    00021         typedef C                          ContainerType;
    00022         typedef typename C::iterator       iterator;
    00023         typedef typename C::const_iterator const_iterator;
    00024         typedef s_range<iterator>          range;
    00025         typedef s_range<const_iterator>    const_range;
    00026
    00027         /// Default constructor.
    00028         s_ctnr_t()
    00029         {
    00030         }
    00031
    00032         /// Destructor.
    00033         virtual ~s_ctnr_t()
    00034         {
    00035         }
    00036
    00037         /// Copy constructor.
    00038         s_ctnr_t(const s_ctnr_t& mCtnr)
    00039         {
    00040             mContainer_ = mCtnr.mContainer_;
    00041         }
    00042
    00043         /// Conversion constructor.
    00044         template<class N, class M>
    00045         s_ctnr_t(const s_ctnr_t<N, M>& mCtnr)
    00046         {
    00047             typename s_ctnr_t<N, M>::const_iterator iter;
    00048             for (iter = mCtnr.Begin(); iter != mCtnr.End(); ++iter)
    00049                 mContainer_.push_back(*iter);
    00050         }
    00051
    00052         /// Constructor.
    00053         /** \param mElem The first element of the sequence
    00054         *   \note You can use this constructor, but it's main use is to build
    00055         *         s_ctnr_t by enclosing a series of values by parenthesis (if these
    00056         *         values have implemented the ',' operator).
    00057         */
    00058         s_ctnr_t(const ValueType& mElem)
    00059         {
    00060             mContainer_.push_back(mElem);
    00061         }
    00062
    00063         #ifdef CPP_0X
    00064             /// Initializer list constructor.
    00065             /** \param mList Brace enclosed element list
    00066             *   \note This constructor uses a C++0x feature.<br>
    00067             *         It allows : s_ctnr_t<s_int> v = {1, 2, 3, 4};
    00068             */
    00069             s_ctnr_t(std::initializer_list<ValueType> mList)
    00070             {
    00071                 for (const ValueType* p = mList.begin(); p != mList.end(); ++p)
    00072                     mContainer_.push_back(*p);
    00073             }
    00074         #endif
    00075
    00076         /// Constructor.
    00077         /** \param lElemArray The array to use to initialize this s_ctnr_t
    00078         *   \note Takes every elements contained by the s_array and puts them
    00079         *         inside this s_ctnr_t.
    00080         */
    00081         template<default_uint N>
    00082         s_ctnr_t(const s_array<ValueType,N>& lElemArray)
    00083         {
    00084             for (default_uint i = 0; i < N; ++i)
    00085                 mContainer_.push_back(lElemArray[i]);
    00086         }
    00087
    00088         /// Returns the last element of this container.
    00089         /** \return The last element of this container
    00090         *   \note You should check this container is not empty
    00091         *         before calling this function.
    00092         */
    00093         ValueType& Back()
    00094         {
    00095             return mContainer_.back();
    00096         }
    00097
    00098         /// Returns the last element of this container.
    00099         /** \return The last element of this container
    00100         *   \note You should check this container is not empty
    00101         *         before calling this function.
    00102         */
    00103         const ValueType& Back() const
    00104         {
    00105             return mContainer_.back();
    00106         }
    00107
    00108         /// Adds a value at the end of the container.
    00109         /** \param mElem The value to add
    00110         */
    00111         void PushBack(const ValueType& mElem)
    00112         {
    00113             mContainer_.push_back(mElem);
    00114         }
    00115
    00116         /// Adds a set of values at the end of the container.
    00117         /** \param lArray The array of value to add
    00118         *   \note Order is preserved.
    00119         */
    00120         void PushBack(const s_ctnr_t& lArray)
    00121         {
    00122             const_iterator iter;
    00123             for (iter = lArray.begin(); iter != lArray.end(); ++iter)
    00124                 mContainer_.push_back(*iter);
    00125         }
    00126
    00127         /// Removes the last value of the container.
    00128         void PopBack()
    00129         {
    00130             mContainer_.pop_back();
    00131         }
    00132
    00133         /// Removes values from the end of the container.
    00134         /** \param uiNbr The number of value to remove
    00135         */
    00136         void PopBack(const s_uint_t<default_uint>& uiNbr)
    00137         {
    00138             if (uiNbr >= mContainer_.size())
    00139                 mContainer_.clear();
    00140             else
    00141             {
    00142                 for (default_uint ui = 0; ui < uiNbr.Get(); ++ui)
    00143                     mContainer_.pop_back();
    00144             }
    00145         }
    00146
    00147         /// Returns the first element of this container.
    00148         /** \return The first element of this container
    00149         *   \note You should check this container is not empty
    00150         *         before calling this function.
    00151         */
    00152         ValueType& Front()
    00153         {
    00154             return mContainer_.front();
    00155         }
    00156
    00157         /// Returns the first element of this container.
    00158         /** \return The first element of this container
    00159         *   \note You should check this container is not empty
    00160         *         before calling this function.
    00161         */
    00162         const ValueType& Front() const
    00163         {
    00164             return mContainer_.front();
    00165         }
    00166
    00167         /// Adds a value at the beginning of the container.
    00168         /** \param mElem The value to add
    00169         */
    00170         void PushFront(const ValueType& mElem)
    00171         {
    00172             mContainer_.push_front(mElem);
    00173         }
    00174
    00175         /// Adds a set of values at the beginning of the container.
    00176         /** \param lArray The array of value to add
    00177         *   \note Order is preserved.
    00178         */
    00179         void PushFront(const s_ctnr_t& lArray)
    00180         {
    00181             const_iterator iter = lArray.end();
    00182             while (iter != lArray.begin())
    00183             {
    00184                 --iter;
    00185                 mContainer_.push_front(*iter);
    00186             }
    00187         }
    00188
    00189         /// Removes the first value of the container.
    00190         void PopFront()
    00191         {
    00192             mContainer_.pop_front();
    00193         }
    00194
    00195         /// Removes values from the beginning of the container.
    00196         /** \param uiNbr The number of value to remove
    00197         */
    00198         void PopFront(const s_uint_t<default_uint>& uiNbr)
    00199         {
    00200             if (uiNbr >= mContainer_.size())
    00201                 mContainer_.clear();
    00202             else
    00203             {
    00204                 for (default_uint ui = 0; ui < uiNbr.Get(); ++ui)
    00205                     mContainer_.pop_front();
    00206             }
    00207         }
    00208
    00209         /// Removes all elements from this container.
    00210         void Clear()
    00211         {
    00212             mContainer_.clear();
    00213         }
    00214
    00215         /// Inserts or erases elements from the end of this container.
    00216         /** \param uiSize The new size of the container
    00217         *   \param mElem  The dummy element to append is the new size is
    00218         *                 greater than the current one
    00219         *   \note If uiSize is superior to the container's current size,
    00220         *         mElem is appended as many time as neccessary to fit the
    00221         *         new size. Else, elements are erased.
    00222         */
    00223         void Resize(const s_uint_t<default_uint>& uiSize, const ValueType& mElem = ValueType())
    00224         {
    00225             mContainer_.resize(uiSize.Get(), mElem);
    00226         }
    00227
    00228         /// Searches the container for the provided element.
    00229         /** \param mElem   The element to search for
    00230         *   \return 'true' if the element has been found
    00231         */
    00232         s_bool Find(const ValueType& mElem) const
    00233         {
    00234             return (std::find(mContainer_.begin(), mContainer_.end(), mElem) != mContainer_.end());
    00235         }
    00236
    00237         /// Searches the container for the provided element.
    00238         /** \param mElem   The element to search for
    00239         *   \param uiStart The position from which to start searching
    00240         *   \return 'true' if the element has been found
    00241         */
    00242         s_bool Find(const ValueType& mElem, const s_uint_t<default_uint>& uiStart) const
    00243         {
    00244             return (std::find(mContainer_.begin() + uiStart.Get(), mContainer_.end(), mElem) != mContainer_.end());
    00245         }
    00246
    00247         /// Searches the container for the provided element.
    00248         /** \param mElem   The element to search for
    00249         *   \return The position of the element in the container
    00250         *   \note If the element is not present in the container, this function
    00251         *         returns s_uint::NaN.
    00252         */
    00253         s_uint_t<default_uint> FindPos(const ValueType& mElem) const
    00254         {
    00255             const_iterator iterPos = std::find(mContainer_.begin(), mContainer_.end(), mElem);
    00256             if (iterPos == mContainer_.end())
    00257                 return s_uint_t<default_uint>::NaN;
    00258             else
    00259                 return iterPos - mContainer_.begin();
    00260         }
    00261
    00262         /// Searches the container for the provided element.
    00263         /** \param mElem   The element to search for
    00264         *   \param uiStart The position from which to start searching
    00265         *   \return The position of the element in the container
    00266         *   \note If the element is not present in the container, this function
    00267         *         returns s_uint::NaN.
    00268         */
    00269         s_uint_t<default_uint> FindPos(const ValueType& mElem, const s_uint_t<default_uint>& uiStart) const
    00270         {
    00271             const_iterator iterPos = std::find(mContainer_.begin() + uiStart.Get(), mContainer_.end(), mElem);
    00272             if (iterPos == mContainer_.end())
    00273                 return s_uint_t<default_uint>::NaN;
    00274             else
    00275                 return (default_uint)(iterPos - mContainer_.begin());
    00276         }
    00277
    00278         /// Searches the container for the provided element.
    00279         /** \param mElem   The element to search for
    00280         *   \note If the element is not present in the container, this function
    00281         *         returns End().
    00282         */
    00283         iterator Get(const ValueType& mElem)
    00284         {
    00285             return std::find(mContainer_.begin(), mContainer_.end(), mElem);
    00286         }
    00287
    00288         /// Searches the container for the provided element.
    00289         /** \param mElem   The element to search for
    00290         *   \param uiStart The position from which to start searching
    00291         *   \return An iterator pointing to this element
    00292         *   \note If the element is not present in the container, this function
    00293         *         returns End().
    00294         */
    00295         iterator Get(const ValueType& mElem, const s_uint_t<default_uint>& uiStart)
    00296         {
    00297             iterator iterStart = mContainer_.begin() + uiStart.Get();
    00298             return std::find(iterStart, mContainer_.end(), mElem);
    00299         }
    00300
    00301         /// Searches the container for the provided element.
    00302         /** \param mElem   The element to search for
    00303         *   \return An iterator pointing to this element
    00304         *   \note If the element is not present in the container, this function
    00305         *         returns End().
    00306         */
    00307         const_iterator Get(const ValueType& mElem) const
    00308         {
    00309             return std::find(mContainer_.begin(), mContainer_.end(), mElem);
    00310         }
    00311
    00312         /// Searches the container for the provided element.
    00313         /** \param mElem   The element to search for
    00314         *   \param uiStart The position from which to start searching
    00315         *   \return An iterator pointing to this element
    00316         *   \note If the element is not present in the container, this function
    00317         *         returns End().
    00318         */
    00319         const_iterator Get(const ValueType& mElem, const s_uint_t<default_uint>& uiStart) const
    00320         {
    00321             const_iterator iterStart = mContainer_.begin() + uiStart.Get();
    00322             return std::find(iterStart, mContainer_.end(), mElem);
    00323         }
    00324
    00325         /// Inserts an element before mIter.
    00326         /** \param mIter  The reference iterator
    00327         *   \param mValue The value to insert
    00328         *   \return An iterator pointing to the inserted value
    00329         */
    00330         iterator Insert(const iterator& mIter, const T& mValue)
    00331         {
    00332             return mContainer_.insert(mIter, mValue);
    00333         }
    00334
    00335         /// Inserts all values in a range before mIter.
    00336         /** \param mIter  The reference iterator
    00337         *   \param mRange The range containing values to insert
    00338         *   \return An iterator pointing to the last inserted value
    00339         *   \note The last element of the range will not be inserted.
    00340         */
    00341         iterator Insert(const iterator& mIter, const range& mRange)
    00342         {
    00343             iterator mTempIter = mIter;
    00344             --mTempIter;
    00345             mContainer_.insert(mIter, mRange.Begin(), mRange.End());
    00346             return mTempIter + (mRange.End() - mRange.Begin());
    00347         }
    00348
    00349         /// Inserts the content of a container before mIter.
    00350         /** \param mIter      The reference iterator
    00351         *   \param mContainer The container to insert
    00352         *   \return An iterator pointing to the last inserted value
    00353         */
    00354         iterator Insert(const iterator& mIter, const s_ctnr_t& mContainer)
    00355         {
    00356             iterator mTempIter = mIter;
    00357             --mTempIter;
    00358             mContainer_.insert(mIter, mContainer.Begin(), mContainer.End());
    00359             return mTempIter + mContainer.mContainer_.size();
    00360         }
    00361
    00362         /// Erases an element from the container.
    00363         /** \param uiPos The position of the element to erase
    00364         */
    00365         void Erase(const s_uint_t<default_uint>& uiPos)
    00366         {
    00367             if (uiPos.IsValid() && uiPos < mContainer_.size())
    00368                 mContainer_.erase(mContainer_.begin() + uiPos.Get());
    00369         }
    00370
    00371         /// Erases an element from the container.
    00372         /** \param mIter The iterator pointing at the element you want to remove
    00373         *   \return The iterator pointing at the next element in the container
    00374         *   \note If the provided iterator was pointing to the last element, then
    00375         *         End() is returned.
    00376         */
    00377         iterator Erase(const iterator& mIter)
    00378         {
    00379             return mContainer_.erase(mIter);
    00380         }
    00381
    00382         /// Erases a range of elements from the container.
    00383         /** \param uiStart The position from which to start erasing
    00384         *   \param uiEnd   The position at which to stop erasing (exclusive)
    00385         */
    00386         void EraseRange(const s_uint_t<default_uint>& uiStart, const s_uint_t<default_uint>& uiEnd)
    00387         {
    00388             if (uiStart.IsValid())
    00389             {
    00390                 if (!uiEnd.IsValid())
    00391                     mContainer_.erase(mContainer_.begin() + uiStart.Get(), mContainer_.end());
    00392                 else
    00393                     mContainer_.erase(mContainer_.begin() + uiStart.Get(), mContainer_.begin() + uiEnd.Get());
    00394             }
    00395         }
    00396
    00397         /// Erases a range of elements from the container.
    00398         /** \param mBegin The position from which to start erasing
    00399         *   \param mEnd   The position at which to stop erasing (exclusive)
    00400         *   \return The iterator pointing at the next element in the container
    00401         */
    00402         iterator EraseRange(const iterator& mBegin, const iterator& mEnd)
    00403         {
    00404             return mContainer_.erase(mBegin, mEnd);
    00405         }
    00406
    00407         /// Erases a range of elements from the container.
    00408         /** \param mRange The range to erase
    00409         *   \return The iterator pointing at the next element in the container
    00410         */
    00411         iterator EraseRange(const range& mRange)
    00412         {
    00413             return mContainer_.erase(mRange.Begin(), mRange.End());
    00414         }
    00415
    00416         /// Returns the number of elements in this container.
    00417         /** \return The number of elements in this container
    00418         */
    00419         s_uint_t<default_uint> GetSize() const
    00420         {
    00421             return mContainer_.size();
    00422         }
    00423
    00424         /// Checks if this container is empty.
    00425         /** \return 'true' if this container is empty
    00426         */
    00427         s_bool IsEmpty() const
    00428         {
    00429             return mContainer_.empty();
    00430         }
    00431
    00432         /// Inverts the order of the elements.
    00433         void Reverse()
    00434         {
    00435             std::reverse(mContainer_.begin(), mContainer_.end());
    00436         }
    00437
    00438         /// Sorts the elements of this container according to the "<" operator.
    00439         void Sort()
    00440         {
    00441             std::sort(mContainer_.begin(), mContainer_.end());
    00442         }
    00443
    00444         template<default_uint N>
    00445         s_ctnr_t& operator = (const s_array<ValueType,N>& lElemArray)
    00446         {
    00447             mContainer_.clear();
    00448
    00449             for (default_uint i = 0; i < N; ++i)
    00450                 mContainer_.push_back(lElemArray[i]);
    00451
    00452             return *this;
    00453         }
    00454
    00455         ValueType& operator[] (const s_uint_t<default_uint>& uiIndex)
    00456         {
    00457             return mContainer_[uiIndex.Get()];
    00458         }
    00459
    00460         const ValueType& operator[] (const s_uint_t<default_uint>& uiIndex) const
    00461         {
    00462             return mContainer_[uiIndex.Get()];
    00463         }
    00464
    00465         ValueType& operator[] (const default_uint& uiIndex)
    00466         {
    00467             return mContainer_[uiIndex];
    00468         }
    00469
    00470         const ValueType& operator[] (const default_uint& uiIndex) const
    00471         {
    00472             return mContainer_[uiIndex];
    00473         }
    00474
    00475         iterator Begin()
    00476         {
    00477             return mContainer_.begin();
    00478         }
    00479
    00480         const_iterator Begin() const
    00481         {
    00482             return mContainer_.begin();
    00483         }
    00484
    00485         iterator End()
    00486         {
    00487             return mContainer_.end();
    00488         }
    00489
    00490         const_iterator End() const
    00491         {
    00492             return mContainer_.end();
    00493         }
    00494
    00495         iterator begin()
    00496         {
    00497             return mContainer_.begin();
    00498         }
    00499
    00500         const_iterator begin() const
    00501         {
    00502             return mContainer_.begin();
    00503         }
    00504
    00505         iterator end()
    00506         {
    00507             return mContainer_.end();
    00508         }
    00509
    00510         const_iterator end() const
    00511         {
    00512             return mContainer_.end();
    00513         }
    00514
    00515     protected :
    00516
    00517         ContainerType mContainer_;
    00518     };
    00519
    00520     /// Simple container.
    00521     /** Implemented with std::deque : supports fast operations
    00522     *   at both begin and end of the container.<br>
    00523     *   Usefull for unordered list of elements.
    00524     */
    00525     template<class T>
    00526     class s_ctnr : public s_ctnr_t< T, std::deque<T> >
    00527     {
    00528     public :
    00529
    00530         typedef T                            ValueType;
    00531         typedef s_ctnr_t< T, std::deque<T> > ParentContainerType;
    00532
    00533         s_ctnr() : ParentContainerType() {}
    00534
    00535         s_ctnr(const ValueType& mElem) : ParentContainerType(mElem) {}
    00536
    00537         #ifdef CPP_0X
    00538             s_ctnr(std::initializer_list<ValueType> mList) : ParentContainerType(mList) {}
    00539         #endif
    00540
    00541         template<default_uint N>
    00542         s_ctnr(const s_array<ValueType,N>& lElemArray) : ParentContainerType(lElemArray) {}
    00543
    00544         s_ctnr(const ParentContainerType& mCtnr) : ParentContainerType(mCtnr) {}
    00545
    00546         s_ctnr& operator, (const ValueType& mElem)
    00547         {
    00548             PushBack(mElem);
    00549             return (*this);
    00550         }
    00551     };
    00552
    00553     /// Dynamic array.
    00554     /** Implemented with std::vector : supports fast operations
    00555     *   at the end of the container.<br>
    00556     *   It's main advantage over s_ctnr is that you can get a pointer
    00557     *   to the data it contains, if you need to feed it to an external
    00558     *   library without bothering with dynamic allocations and classic
    00559     *   C arrays.<br>
    00560     *   Use the Reserve() function to allocate the needed space : it will
    00561     *   greatly improve performances.
    00562     */
    00563     template<class T>
    00564     class s_array<T,0> : public s_ctnr_t< T, std::vector<T> >
    00565     {
    00566     public :
    00567
    00568         typedef T                             ValueType;
    00569         typedef s_ctnr_t< T, std::vector<T> > ParentContainerType;
    00570         using ParentContainerType::mContainer_;
    00571
    00572         s_array() : ParentContainerType() {}
    00573
    00574         s_array(const ValueType& mElem) : ParentContainerType(mElem) {}
    00575
    00576         #ifdef CPP_0X
    00577             s_array(std::initializer_list<ValueType> mList) : ParentContainerType(mList) {}
    00578         #endif
    00579
    00580         template<default_uint N>
    00581         s_array(const s_array<ValueType,N>& lElemArray) : ParentContainerType(lElemArray) {}
    00582
    00583         s_array(const ParentContainerType& mCtnr) : ParentContainerType(mCtnr) {}
    00584
    00585         s_array(const s_ctnr_t< T, std::deque<T> >& mCtnr) : ParentContainerType(mCtnr) {}
    00586
    00587         /// Returns the underlying C array.
    00588         /** \return The underlying C array
    00589         */
    00590         ValueType* GetClassicArray()
    00591         {
    00592             return &mContainer_[0];
    00593         }
    00594
    00595         /// Reserves some space in memory.
    00596         /** \param uiSize The requested space
    00597         *   \note Can be used to reduce the number of allocations
    00598         *         and improve performances.
    00599         */
    00600         void Reserve(const s_uint_t<default_uint>& uiSize)
    00601         {
    00602             mContainer_.reserve(uiSize.Get());
    00603         }
    00604     };
    00605
    00606     /** \cond NOT_REMOVE_FROM_DOC
    00607     */
    00608     template<class T, class C> class StringConverter< string_element, s_ctnr_t<T,C> >
    00609     {
    00610     public :
    00611
    00612         typedef typename s_str::string string;
    00613
    00614         static string Convert(const s_ctnr_t<T,C>& mCtnr)
    00615         {
    00616             string sTemp = "(";
    00617             typename s_ctnr_t<T,C>::const_iterator iter;
    00618             for (iter = mCtnr.Begin(); iter != mCtnr.End(); ++iter)
    00619             {
    00620                 if (iter != mCtnr.Begin())
    00621                     sTemp += ", " + StringConverter<string_element, T>::Convert(*iter);
    00622                 else
    00623                     sTemp += StringConverter<string_element, T>::Convert(*iter);
    00624             }
    00625             sTemp += ")";
    00626
    00627             return sTemp;
    00628         }
    00629     };
    00630
    00631     template<class T> class StringConverter< string_element, s_ctnr<T> >
    00632     {
    00633     public :
    00634
    00635         typedef typename s_str::string string;
    00636
    00637         static string Convert(const s_ctnr<T>& mCtnr)
    00638         {
    00639             string sTemp = "(";
    00640             typename s_ctnr<T>::const_iterator iter;
    00641             for (iter = mCtnr.Begin(); iter != mCtnr.End(); ++iter)
    00642             {
    00643                 if (iter != mCtnr.Begin())
    00644                     sTemp += ", " + StringConverter<string_element, T>::Convert(*iter);
    00645                 else
    00646                     sTemp += StringConverter<string_element, T>::Convert(*iter);
    00647             }
    00648             sTemp += ")";
    00649
    00650             return sTemp;
    00651         }
    00652     };
    00653
    00654     template<class T> class StringConverter< string_element, s_array<T,0> >
    00655     {
    00656     public :
    00657
    00658         typedef typename s_str::string string;
    00659
    00660         static string Convert(const s_array<T,0>& mCtnr)
    00661         {
    00662             string sTemp = "(";
    00663             typename s_array<T,0>::const_iterator iter;
    00664             for (iter = mCtnr.Begin(); iter != mCtnr.End(); ++iter)
    00665             {
    00666                 if (iter != mCtnr.Begin())
    00667                     sTemp += ", " + StringConverter<string_element, T>::Convert(*iter);
    00668                 else
    00669                     sTemp += StringConverter<string_element, T>::Convert(*iter);
    00670             }
    00671             sTemp += ")";
    00672
    00673             return sTemp;
    00674         }
    00675     };
    00676     /** \endcond
    00677     */
    00678
    00679     template<class T>
    00680     s_ctnr<s_bool> operator, (const s_bool& mLeft, const s_bool& mRight)
    00681     {
    00682         s_ctnr<s_bool> mCtnr;
    00683         mCtnr.PushBack(mLeft);
    00684         mCtnr.PushBack(mRight);
    00685         return mCtnr;
    00686     }
    00687     template<class T>
    00688     s_ctnr< s_int_t<T> > operator, (const s_int_t<T>& mLeft, const s_int_t<T>& mRight)
    00689     {
    00690         s_ctnr< s_int_t<T> > mCtnr;
    00691         mCtnr.PushBack(mLeft);
    00692         mCtnr.PushBack(mRight);
    00693         return mCtnr;
    00694     }
    00695     template<class T>
    00696     s_ctnr< s_uint_t<T> > operator, (const s_uint_t<T>& mLeft, const s_uint_t<T>& mRight)
    00697     {
    00698         s_ctnr< s_uint_t<T> > mCtnr;
    00699         mCtnr.PushBack(mLeft);
    00700         mCtnr.PushBack(mRight);
    00701         return mCtnr;
    00702     }
    00703     template<class T>
    00704     s_ctnr< s_float_t<T> > operator, (const s_float_t<T>& mLeft, const s_float_t<T>& mRight)
    00705     {
    00706         s_ctnr< s_float_t<T> > mCtnr;
    00707         mCtnr.PushBack(mLeft);
    00708         mCtnr.PushBack(mRight);
    00709         return mCtnr;
    00710     }
    00711     template<class T>
    00712     s_ctnr< s_str_t<T> > operator, (const s_str_t<T>& mLeft, const s_str_t<T>& mRight)
    00713     {
    00714         s_ctnr< s_str_t<T> > mCtnr;
    00715         mCtnr.PushBack(mLeft);
    00716         mCtnr.PushBack(mRight);
    00717         return mCtnr;
    00718     }
    00719 }