This discussion is archived
8 Replies Latest reply: Jul 9, 2013 3:45 AM by user12982757 RSS

Differnce between LibCstd and LibStlport

889316 Newbie
Currently Being Moderated
Hi

what is the main difference if we Build application with LibCStd and LibStlport
  • 1. Re: Differnce between LibCstd and LibStlport
    Steve_Clamage Pro
    Currently Being Moderated
    libCstd and STLport are different and incompatible implementations of the C++ standard library. Each uses its own set of (incompatible) headers, chosen automatically by the compiler based on the -library=xxx option. Binaries built to use libCstd cannot be linked successfully with binaries built to use STLport.

    libCstd pros:
    It is the default library, and the runtime binary ships as part of Solaris. Applications built to use libCstd will run on Solaris; you don't have to ship libCstd with the application.
    libCstd supports locales for I18N and L10N purposes.

    libCstd cons:
    Not very standard-conforming. Library features that depend on template members of standard classes are not available.
    In particular, very little of BOOST will compile if you use libCstd.

    STLport pros:
    Much more standard-conforming. BOOST works well with it.

    STLport cons:
    If you ship an application that uses STLport, you need to ship libstlport.so.1 with it, or link libstlport.a statically.
    STLport has no support for locales, so applications needing I18N and L10N will not work well.

    A third choice is available on Solaris 11: the Apache stdcxx implementation that ships as part of Solaris. This library is a complete implementation of the C++ standard library. The option
    -library=stdcxx4
    allows you to use this library, which is incompatible with both libCstd and STLport. It has the advantages of both, and the disadvantages of neither. I hoped that a patch to install this library would be available for Solaris 10, but so far the library is limited to Solaris 11.

    Edited by: Steve_Clamage on Sep 29, 2011 10:20 AM
  • 2. Re: Differnce between LibCstd and LibStlport
    877216 Newbie
    Currently Being Moderated
    To expand on what Steve wrote:
    >
    libCstd cons:
    Not very standard-conforming. Library features that depend on template members of standard classes are not available.
    >

    This means in effect that the implementation of the Standard Template Library in libCstd is not complete, thus for instance the following testcase won't compile with <tt>-library=Cstd</tt> (default), though it's OK with <tt>-library=stdcxx4</tt> or <tt>-library=stlport4</tt>.
    #include <stdlib.h>
    #include <vector>
    #include <iostream>
    using namespace std;
     
    int main(int argc, char** argv) {
            vector<int> myvec;
            myvec.assign(7,42);
     
            vector<int>::iterator second=&myvec[1];
            vector<int>::iterator last=myvec.end();
     
            cout << "Distance between second and last element of vector " << distance(second, last) << endl;
            return EXIT_SUCCESS;
    }
  • 3. Re: Differnce between LibCstd and LibStlport
    Steve_Clamage Pro
    Currently Being Moderated
    I said earlier that stdcxx was not available on Solaris 10.
    In fact, it is included in Solaris 10 update 10, and will also be in any future updates.
    It is not available as a patch to earlier versions of Solaris 10, however.
  • 4. Re: Differnce between LibCstd and LibStlport
    902766 Newbie
    Currently Being Moderated
    libCstd is potentially probably more standard-conforming than STLport
    In fact the Apache stdcxx is derived from the same roots - libCstd is just an older version of RogueWave Standard C++ Library

    All the seemingly missing parts are actually implemented in the headers but switched off by configuration macros setup in <tt>/opt/solstudio12.2/prod/include/CC/Cstd/stdcomp.h</tt>
    The configuration is by no means obtained from the automatic script (as suggested in the header itself) and it presents <tt>CC</tt> as an incapable old-fashioned pre-standard compiler (like from the times of SPARCWorks) that does not understand many advanced template features needed for implementating full standard by the library

    One has three choices to unlock standard features in libCstd:
    <ol>
    <li> Edit the <tt>CC/Cstd/stdcomp.h</tt> and make the following macros undefined (easier by commenting out their definitions)

    </li>
    <li> Create a file named <tt>stdcomp.h</tt>, fill it with properly edited contents and add the path using <tt>-I</tt> directive. This will cause the compiler to use created file instead of the original </li>
    <li> Create a file named <tt>stdcomp.h</tt> that will <tt>#include</tt> the original and adjust the macros. As with 2. include path needs to be provided with <tt>-I</tt>

    The fixed <tt>stdcomp.h</tt> header should look like:
    #ifndef _FIXED_STDCOMP_INCLUDED_
    #define _FIXED_STDCOMP_INCLUDED_
    
    // Include the original
    #include <Cstd/stdcomp.h>
    
    // Clear offending macros
    #undef _RWSTD_NO_MEMBER_TEMPLATES
    #undef RWSTD_NO_MEMBER_TEMPLATES
    #undef _RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES
    #undef _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
    #undef _RWSTD_NO_FRIEND_TEMPLATES
    #undef RWSTD_NO_FRIEND_TEMPLATES
    #undef _RWSTD_NO_MEM_CLASS_TEMPLATES
    #undef RWSTD_NO_MEM_CLASS_TEMPLATES
    #undef _RWSTD_NO_TEMPLATE_TEMPLATE
    #undef RWSTD_NO_TEMPLATE_TEMPLATE
    #undef _RWSTD_NO_EXPLICIT_ARG
    #undef RWSTD_NO_EXPLICIT_ARG
    #undef _RWSTD_NO_STATIC_MEM_DEF
    #undef RWSTD_NO_STATIC_MEM_DEF
    #undef _RWSTD_NO_DEFAULT_FOR_TPARAM
    #undef RWSTD_NO_DEFAULT_FOR_TPARAM
    #undef _RWSTD_NO_PART_SPEC_OVERLOAD
    #undef RWSTD_NO_PART_SPEC_OVERLOAD
    #undef _RWSTD_NO_INIT_CONST_TEMPLATE_REF_ARG
    #undef RWSTD_NO_INIT_CONST_TEMPLATE_REF_ARG
    #undef _RWSTD_NO_CLASS_PARTIAL_SPEC
    #undef RWSTD_NO_CLASS_PARTIAL_SPEC
    #undef _RWSTD_NO_FUNC_PARTIAL_SPEC
    #undef RWSTD_NO_FUNC_PARTIAL_SPEC
    #undef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    #undef RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    
    // prevent the original from #define'ing the macros again
    #define RW_NEVER_ENTER_DEFAULT_HEADER_BLOCK 1
    
    // clear inclusion guard
    #undef __STD_RWCOMPILER_H__
    // include original once more
    #include <Cstd/stdcomp.h>
    
    // macro from stdcxx-4.x.x, used by vector<bool>
    #if defined(_RWSTD_ALLOCATOR) && !defined(_HPACC_)
    # define _RWSTD_REBIND(alloc, type) _TYPENAME alloc::template rebind<type>::other
    #else
    # define _RWSTD_REBIND(alloc, type) allocator_interface<alloc, type>
    #endif
    
    #endif
    Double inclusion of original header is necessary because more macros will be defined after our #undefine's

    To prevent warnings about macros redefinition with second include more #undef's can be added, e.g. for <tt>RWSTDVER</tt>, <tt>RWSTD</tt> or <tt>__RWSTD</tt>

    The purpose of macro <tt>RWSTDREBIND</tt> will get clear in the following discussion. One may wish to add this definition if editing the original file in place.
    </li>
    </ol>

    No matter which solution is chosen there are a few other considerations:
    <ol>
    <li><tt>CC</tt> by default has implicit inclusion feature - it automatically includes files with template implementation during compilation. For a header <tt>name.extension</tt> it looks for files <tt>name.cc</tt> and <tt>name.cpp</tt> on include path and uses them without an explicit <tt>#include "name.cc"</tt>. This feature is used by <tt>libCstd</tt>, e.g. <tt><vector></tt> header includes <tt>vector.cc</tt> only if <tt>RWSTDCOMPILE_INSTANTIATE</tt> macro is defined (by default it is undefined).

    Though the feature is useful it may cause problems when a header named like one of the standard library is used (e.g. <tt><boost/container/vector.hpp></tt>). The compiler looks for an implementation file and uses the one from libCstd (<tt>CC/Cstd/vector.cc</tt> in this case). As the corresponding standard header has not been included it complains about defining methods for non-existing template class <tt>std::vector</tt>.

    If <tt>Boost.Container</tt> or other similar library is to be used one should add <tt>-template=no%extdef</tt> compiler option and define the macro <tt>RWSTDCOMPILE_INSTANTIATE</tt>.
    <li>Changes to <tt><stdcomp.h></tt> turns <tt>std::iterator_traits</tt> template on but the corresponding <tt>__iterator_category</tt> function specialization is missing. The best place for it is standard <tt><iterator></tt> header:
    #ifndef _ITERATOR_FIX_INCLUDED_
    #define _ITERATOR_FIX_INCLUDED_
    
    #include <Cstd/iterator>
    
    namespace _RW_STD {
    
    template<typename _IterT>
    inline typename iterator_traits<_IterT>::iterator_category
    __iterator_category(const _IterT&)
    {
        return typename iterator_traits<_IterT>::iterator_category();
    }
    
    }
    
    #endif // _ITERATOR_FIX_INCLUDED_
    Note that the hacked file should be named <tt>iterator.SUNWCCh</tt> to be used by the compiler. CC does not include standard headers from files without that extension
    (of course one may edit <tt>CC/Cstd/iterator.SUNWCCh</tt> file directly)</li>
    <li>The changes unlock templatized constructor in <tt>std::pair</tt> class which can lead to ambiguity between overloads of <tt>insert</tt> methods of <tt>std::map</tt> container, namely
    pair<iterator, bool> insert(const value_type&);  // value_type is a typedef for pair<const key_type, mapped_type>
    pair<iterator, bool> insert(const pair<key_type, mapped_type>&);
    when called with an argument like <tt>std::make_pair(key, value)</tt> the compiler is not able to choose overload because the templatized <tt>pair</tt> constructor can convert between pairs that only differ in constantness of their components

    This time there is no <tt>#include</tt>-then-fix solution - one may edit the original <tt>CC/Cstd/map.SUNWCCh</tt> file or copy its contents to another location (again, remember about <tt>.SUNWCCh</tt> extension) and edit it there.

    The fix is to remove method
        pair<iterator, bool> insert (const pair<key_type, mapped_type> &__x)
    Best may be using conditional:
    #ifdef _RWSTD_NO_MEMBER_TEMPLATES
        pair<iterator, bool> insert (const pair<key_type, mapped_type> &__x)
    //... implementation
    #endif
    Be aware it is <tt>#ifdef</tt> here (not <tt>#ifndef</tt>) so the code gets excluded as <tt>RWSTDNO_MEMBER_TEMPLATES</tt> has been undefined
    </li>
    <li>With full partial template specialization support turned on we get into troubles with <tt>std::vector<bool></tt> class. The compiler complains that <tt>__first.p</tt> is inaccessible from <tt>vector<bool>::~vector()</tt> though <tt>vector<bool>::iterator</tt> contains
    friend class vector<bool, Allocator>;
    Changing that to
    friend class vector;
    fooled the compiler in full:
    >
    <tt>>> Assertion: (../lnk/ftemplate.cc, line 498)
    while processing libs/program_options/src/options_description.cpp at line 242</tt>
    >
    This looks like error in the compiler, in other contexts friend declarations in partially specialized classes work. When using <tt>CC</tt> compiler I found several times that a problematic code construct starts working in isolation.

    Returning to the <tt>std::vector<bool></tt> issue I found that putting the implementation from stdcxx 4.3.0 works. Thus one needs to edit (or copy and fix) <tt>CC/Cstd/vector.SUNWCCh</tt> and <tt>CC/Cstd/vector.cc</tt> files

    I provide here the changes for impatient, as this is not a direct copy-paste (some macros in 4.3.0 need changing to their 2.2.1 (i.e. libCstd) equivalents)

    In <tt>vector.SUNWCCh</tt> file replace vector<bool>specialization with
    #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
    
    template <class _Allocator>
    class
    
    #else   // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
    
         // use a macro to mutate _Allocator into allocator<bool>
    # define _Allocator allocator<bool>
    
    _RWSTD_TEMPLATE
    class _RWSTDExport
    
    #endif  // _RWSTD_NO_CLASS_PARTIAL_SPEC
    
    vector<bool, _Allocator >: private _Allocator
    {
        typedef _RWSTD_REBIND(_Allocator, unsigned int)       _C_value_alloc_type;
        typedef vector                                        _C_self;
    public:
    
        typedef _Allocator                                      allocator_type;
        typedef bool                                            value_type;
    
        typedef _TYPENAME allocator_type::size_type             size_type;
        typedef _TYPENAME allocator_type::difference_type       difference_type;
        typedef _TYPENAME _C_value_alloc_type::pointer          pointer;
        typedef _TYPENAME _C_value_alloc_type::const_pointer    const_pointer;
    
        class iterator;
        class const_iterator;
    
        class reference {
    
    #if !defined (__INTEL_COMPILER) || !defined (_MSC_VER)
            // avoid MSVC 6.0 bug 576
            friend class iterator;
    #else   // if Intel C++ 8.1 with MSVC
            // work around Intel C++ 8.1 bug 575
            friend class _C_self::iterator;
    #endif   // Intel C++ with MSVC
    
            friend class const_iterator;
    
        private:
    
            unsigned int* _C_p;
            unsigned int _C_mask;
            reference (unsigned int* __x, unsigned int __y)
                : _C_p (__x), _C_mask (__y) { }
        public:
    
            reference () : _C_p (), _C_mask () {}
    
            operator bool () const {
                return !!(*_C_p & _C_mask);
            }
    
            reference& operator= (bool __x) {
                if (__x)      
                    *_C_p |= _C_mask;
                else
                    *_C_p &= ~_C_mask;
                return *this;
            }
    
            reference& operator= (const reference& __x) {
                return *this = bool(__x);
            }
    
    #ifndef _RWSTD_STRICT_ANSI
    
          bool operator== (const reference& __x) const {
              return bool(*this) == bool(__x);
          }
    
          bool operator< (const reference& __x) const {
    #ifndef _MSC_VER
              return bool(*this) < bool(__x);
    #else
              return int(*this) < int(__x);
    #endif
          }
    
            bool operator!= (const reference& __x) const {
                return !(*this == __x);
            }
    
            bool operator> (const reference& __x) const {
                return  __x < *this;
            }
    
            bool operator>= (const reference& __x) const {
                return !(*this < __x);
            }
    
            bool operator<= (const reference& __x) const {
                return !(*this > __x);
            }
    
    #endif // _RWSTD_STRICT_ANSI
    
            void flip () {
                *_C_p ^= _C_mask;
            }
        };
        
        typedef bool const_reference;
    
        // hacks working around bogus g++ 2.95.2 warnings coming out of
        // iterators below as well as what's probably an MSVC 6.0 bug
        typedef reference       _C_ref;
        typedef const_reference _C_const_ref;
        typedef difference_type _C_diff_t;
    
        class _C_iter {
            friend class iterator;
            friend class const_iterator;
    
        private:
    
    #if defined (__GNUG__)
            // gcc 3.0.1 and prior take 14.5.3, p9 literally
        public:
    #elif    defined (_MSC_VER) && _MSC_VER <= 1300 || defined (__APOGEE__)
            friend class vector<bool, _Allocator>;
    #else
            friend class vector;
    #endif
            unsigned int* _C_p;        // pointer to the current word
            unsigned int  _C_offset;   // number of the pointed-to bit
    
            _C_iter (unsigned int* __x = 0, unsigned int __y = 0)
                : _C_p (__x), _C_offset (__y) { }
    
            // On Sun, gcc 3.1 does generate an incorrect copy constructor
            // that has as an effect an incompletely/incorrectly initialized 
            // iterator.
    #if    defined (__sun__) && defined (__GNUG__) \
        || defined (__SUNPRO_CC) && defined (__amd64__)
    
            // working around a gcc 3.1 bug on Solaris where the compiler
            // generates bad code for the implicitly defined copy ctor
            // also working around a Sun C++ 5.9 optimizer ICE on x86_64
            // in wide (64-bit) mode (see STDCXX-551)
    
            _C_iter (const _C_iter& __it)
                : _C_p (__it._C_p), _C_offset (__it._C_offset) {}
    #endif   // gcc 3.1/Solaris || Sun C++ 5.9/x86_64
    
            void operator++ () {
                if (_C_offset++ == _RWSTD_WORD_BIT - 1) {
                    _C_offset = 0; 
                    ++_C_p;
                }
            }
    
            void operator-- () {
                if (_C_offset-- == 0) {
                    _C_offset = _RWSTD_WORD_BIT - 1; 
                    --_C_p;
                }
            }
    
            void operator+= (difference_type __i) {
                difference_type __n = __i + _C_offset;
                _C_p += __n / _RWSTD_WORD_BIT;
                __n = __n % _RWSTD_WORD_BIT;
                if (__n < 0) {
                    _C_offset = _RWSTD_STATIC_CAST (unsigned int,
                                                    __n + _RWSTD_WORD_BIT);
                    --_C_p;
                }
                else
                    _C_offset = _RWSTD_STATIC_CAST (unsigned int,__n);
            }
    
        public:
    
            bool operator== (const _C_iter& __x) const {
                return _C_p == __x._C_p && _C_offset == __x._C_offset;
            }
    
            bool operator< (const _C_iter& __x) const {
                return _C_p < __x._C_p ||
                    (_C_p == __x._C_p && _C_offset < __x._C_offset);
            }
    
            bool operator!= (const _C_iter& __x) const {
                return !(*this == __x);
            }
    
            bool operator> (const _C_iter& __x) const {
                return __x < *this;
            }
    
            bool operator>= (const _C_iter& __x) const {
                return !(*this < __x);
            }
    
            bool operator<= (const _C_iter& __x) const {
                return !(*this > __x);
            }
        };
          
        class iterator
            : public _C_iter,
              public _RW_STD::iterator<random_access_iterator_tag,
                                       value_type, _C_diff_t,
                                       pointer, _C_ref> {
        public:
    
            // bring names used in declarations below into scope
            // (dependent base members not visible without qualification)
            typedef _C_ref    reference;
            typedef _C_diff_t difference_type;
    
            iterator (unsigned int *__x = 0, unsigned int __y = 0)
                : _C_iter (__x, __y) { }
    
            reference operator* () const { 
                return reference (this->_C_p, 1U << this->_C_offset); 
            }
    
            iterator& operator++ () {
                return _C_iter::operator++(), *this;
            }
    
            iterator operator++ (int) {
                iterator __tmp = *this;
                ++*this;
                return __tmp;
            }
    
            iterator& operator-- () {
                return _C_iter::operator--(), *this;
            }
    
            iterator operator-- (int) {
                iterator __tmp = *this;
                --*this;
                return __tmp;
            }
    
            iterator& operator+= (difference_type __i) {
                return _C_iter::operator+= (__i), *this;
            }
    
            iterator& operator-= (difference_type __i) {
                *this += -__i;
                return *this;
            }
    
            iterator operator+ (difference_type __i) const {
                iterator __tmp = *this;
                return __tmp += __i;
            }
    
            iterator operator- (difference_type __i) const {
                iterator __tmp = *this;
                return __tmp -= __i;
            }
    
            difference_type operator- (iterator __x) const {
                return   _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
                       + this->_C_offset - __x._C_offset;
            }
    
            reference operator[] (difference_type __i) {
                return *(*this + __i);
            }
    
            friend iterator operator+ (difference_type __i,
                                       const iterator &__x) {
                return __x + __i;
            }
        };
    
        class const_iterator
            : public _C_iter,
              public _RW_STD::iterator<random_access_iterator_tag,
                                       value_type, _C_diff_t,
                                       const_pointer, _C_const_ref> {
        public:
    
            // bring names used in declarations below into scope
            // (dependent base members not visible without qualification)
            typedef _C_const_ref const_reference;
            typedef _C_diff_t    difference_type;
    
            const_iterator (unsigned int *__x = 0, unsigned int __y = 0)
                : _C_iter (__x, __y) { }
    
            const_iterator (const _C_iter &__x)
                : _C_iter (__x) { }
    
            const_reference operator* () const {
                return _C_ref (this->_C_p, 1U << this->_C_offset);
            }
    
            const_iterator& operator++ () {
                return _C_iter::operator++(), *this;
            }
    
            const_iterator operator++ (int) {
                const_iterator __tmp = *this;
                ++*this;
                return __tmp;
            }
    
            const_iterator& operator-- () {
                return _C_iter::operator--(), *this;
            }
    
            const_iterator operator-- (int) {
                const_iterator __tmp = *this;
                --*this;
                return __tmp;
            }
    
            const_iterator& operator+= (difference_type __i) {
                return _C_iter::operator+= (__i), *this;
            }
    
            const_iterator& operator-= (difference_type __i) {
                return *this += -__i;
            }
    
            const_iterator
            operator+ (difference_type __i) const {
                return const_iterator (*this) += __i;
            }
    
            const_iterator operator- (difference_type __i) const {
                return const_iterator (*this) -= __i;
            }
    
            difference_type operator- (const_iterator __x) const {
                return   _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
                       + this->_C_offset - __x._C_offset;
            }
    
            const_reference operator[] (difference_type __i) { 
                return *(*this + __i); 
            }
    
            friend const_iterator operator+ (difference_type __i,
                                             const const_iterator &__x) {
                return __x + __i;
            }
        };
    
    #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC 
    
        typedef _RW_STD::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef _RW_STD::reverse_iterator<iterator>       reverse_iterator;
    
    #else
    
        typedef _RW_STD::reverse_iterator<const_iterator, 
            random_access_iterator_tag, value_type, 
            const_reference, const_pointer, difference_type>
        const_reverse_iterator;
    
        typedef _RW_STD::reverse_iterator<iterator, 
            random_access_iterator_tag, value_type,
            reference, pointer, difference_type>
        reverse_iterator;
    
    #endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC 
    
      private:
        //
        // These private functions are replicas of generic algorithms.
        //  We provide them here to avoid putting instantiations of 
        //  the generic algorithms into an archive or shared library.
        //  This gives you full flexibilty in deciding where you want
        //  to put particular instantiations of the generic 
        //  algorithms.
        //
      
        void _C_fill (iterator __first, iterator __last, bool __val) {
            while (__first != __last) *__first++ = __val;
        }
    
        void _C_fill_n (iterator __first, size_type __n, bool __val) {
            while (__n-- > 0) *__first++ = __val;
        }
    
        template <class _Iterator>
        iterator _C_copy (_Iterator __first, _Iterator __last, iterator __res) {
            while (__first != __last)
                *__res++ = *__first++;
            return __res;
        }
    
        template <class _Iterator>
        iterator
        _C_copy_backward (_Iterator __first, _Iterator __last, iterator __res) {
            while (__first != __last) *--__res = *--__last;
            return __res;
        }
    
    private:
    
        iterator       _C_begin;
        iterator       _C_end;
        unsigned int * _C_bufend;
    
        unsigned int* _C_bit_alloc (size_type __n) {
            return _C_value_alloc_type(*this).
                allocate ((__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT,
                          pointer(_C_begin._C_p));
        }
    
        void _C_init (size_type __n) {
            unsigned int* __q = _C_bit_alloc(__n);
            _C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
            _C_begin  = iterator(__q, 0);
            _C_end    = _C_begin + __n;
        }
    
        void _C_insert (iterator, bool);
    
    public:
    
        vector (const _Allocator&  __alloc = allocator_type ())
            : allocator_type (__alloc), _C_begin(iterator()), _C_end(iterator()), 
            _C_bufend () { }
    
    #if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
        // working around a SunPro 5.3 bug (see PR #25962)
        explicit
    #endif   // SunPro > 5.3
        vector (size_type __n, bool __val = bool (), 
           const _Allocator&  __alloc = allocator_type ())
            : allocator_type (__alloc), _C_bufend () {
          _C_init(__n); 
          unsigned int * __first = _C_begin._C_p;
          size_type __m = (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
          while (__m-- > 0) *__first++ = __val ? ~0 : 0;
        }
    
        vector (const _C_self &__x)
            : allocator_type (__x.get_allocator ()), _C_bufend  () {
            _C_init (__x.size ()); 
            _C_copy (__x.begin (), __x.end (), _C_begin);
        }
    
        template<class _InputIter>
        vector  (_InputIter __first, _InputIter __last)
            : allocator_type (), _C_bufend ()
        {
          size_type __n;
          distance(__first, __last, n);
          _C_init(__n); 
          _C_copy(__first, __last, _C_begin);
        }
      
        ~vector () {
          _C_value_alloc_type(*this).deallocate(_C_begin._C_p,  
            _C_bufend - _C_begin._C_p); 
        }
        _C_self& operator= (const _C_self& __x)
        {
          if (&__x == this) return *this;
          if (__x.size() > capacity())
          {
            _C_value_alloc_type(*this).deallocate(_C_begin._C_p,
              _C_bufend - _C_begin._C_p); 
            _C_init(__x.size());
          }
          _C_copy(__x.begin(), __x.end(), begin());
          _C_end = begin() + __x.size();
          return *this;
        }
    
        template<class _InputIter>
        void assign (_InputIter __first, _InputIter __last) {
            clear ();
            insert (begin (), __first, __last);
        }
    
        void assign (size_type __n, const bool& __x = bool()) { 
            clear ();
            insert (begin (), __n, __x);
        }
    
        allocator_type get_allocator() const {
          return *this;
        }
    
        //
        // iterators
        //
        iterator       begin ()       { return _C_begin; }
        const_iterator begin () const 
        { return const_iterator(_C_begin._C_p,_C_begin._C_offset); }
        iterator       end   ()       { return _C_end; }
        const_iterator end   () const 
        { return const_iterator(_C_end._C_p,_C_end._C_offset); }
    
        reverse_iterator       rbegin () { return reverse_iterator(end()); }
        const_reverse_iterator rbegin () const
        { 
          return const_reverse_iterator(end()); 
        }
        reverse_iterator       rend () { return reverse_iterator(begin()); }
        const_reverse_iterator rend () const
        { 
          return const_reverse_iterator(begin()); 
        }
    
        //
        // capacity
        //
        size_type size     () const { return size_type(end() - begin());  }
        size_type max_size () const {
            return _C_value_alloc_type(*this).max_size();
        }
        void resize (size_type __new_size, bool __c = false);
        size_type capacity () const
        {
          return size_type(const_iterator(_C_bufend, 0) - begin());
        }
        bool empty () const { return begin() == end(); }
        void reserve (size_type __n)
        {
            _RWSTD_THROW(__n > max_size(), length_error,
              __RWSTD::except_msg_string(__RWSTD::__rwse_InvalidSizeParam,
                "vector<bool>::reserve(size_type)",__n,max_size()).msgstr());
    
          if (capacity() < __n)
          {
            unsigned int* __q = _C_bit_alloc(__n);
            _C_end = _C_copy(begin(), end(), iterator(__q, 0));
            _C_value_alloc_type(*this).deallocate(_C_begin._C_p,
                                                 _C_bufend - _C_begin._C_p);
            _C_begin = iterator(__q, 0);
            _C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
          }
        }
    
        //
        // element access
        //
        reference       operator[] (size_type __n)       
        { 
    #ifdef _RWSTD_BOUNDS_CHECKING
    
            _RWSTD_THROW(__n >= size(), out_of_range,
              __RWSTD::except_msg_string(__RWSTD::rwse_OutOfRange,
                "vector<bool>::[](size_type)", __n, size()).msgstr());
    
    #endif   // _RWSTD_BOUNDS_CHECKING
    
          return *(begin() + __n); 
        }
        const_reference operator[] (size_type __n) const 
        { 
    #ifdef _RWSTD_BOUNDS_CHECKING
    
            _RWSTD_THROW(__n >= size(), out_of_range,
              __RWSTD::except_msg_string(__RWSTD::rwse_OutOfRange,
                "vector<bool>::[](size_type) const", __n, size()).msgstr());
    
    #endif   // _RWSTD_BOUNDS_CHECKING
    
          return *(begin() + __n); 
        }
        reference       at (size_type __n)               
        { 
            _RWSTD_THROW(__n >= size(), out_of_range,
              __RWSTD::except_msg_string(__RWSTD::rwse_OutOfRange,
                "vector<bool>::at(size_type)", __n, size ()).msgstr());
    
          return *(begin() + __n); 
        }
        const_reference at (size_type __n) const 
        {
            _RWSTD_THROW(__n >= size(), out_of_range,
              __RWSTD::except_msg_string(__RWSTD::rwse_OutOfRange,
                "vector<bool>::at(size_type) const", __n, size()).msgstr());
    
          return *(begin() + __n); 
        }
        reference       front ()       { return *begin();     }
        const_reference front () const { return *begin();     }
        reference       back  ()       { return *(end() - 1); }
        const_reference back  () const { return *(end() - 1); }
        
        //
        // modifiers
        //
        void push_back (const bool& __x)
        {
            if (_C_end._C_p != _C_bufend) {
                ++_C_end;
                *(_C_end-1) = __x;
            }
            else
                _C_insert(end(), __x);
        }
    
        void pop_back () { --_C_end; }
    
        iterator insert (iterator __it, const bool& __x = bool())
        {
          size_type __n = __it - begin();
          if (_C_end._C_p != _C_bufend && __it == end()) {
              ++_C_end;
              *(_C_end-1) = __x;
          }
          else
            _C_insert(__it, __x);
          return begin() + __n;
        }
    
        void insert (iterator __it, size_type __n, const bool& __x);
    
        template<class _InputIter>
        void insert (iterator __it, _InputIter __first,
                     _InputIter __last);
    
        iterator erase (iterator __it)
        {
          if (!(__it + 1 == end()))
            _C_copy(__it + 1, end(), __it);
          --_C_end;
          return __it;
        }
    
        iterator erase(iterator __first, iterator __last)
        {
          _C_end = _C_copy(__last, end(), __first);
          return __first;
        }
    
        void swap (_C_self& __x)
        {
          if((_C_value_alloc_type)*this == (_C_value_alloc_type)__x)
          {
            _STD::swap (_C_begin,  __x._C_begin);
            _STD::swap (_C_end,    __x._C_end);
            _STD::swap (_C_bufend, __x._C_bufend);
          }
          else
          {
            _C_self _x = *this;
            *this = __x;
            __x=_x;
          } 
        }
    
        static void swap(reference __x, reference __y);
    
        void flip ();
    
        void clear()
        {
          erase(begin(),end());
        }
    
    #if defined (_RWSTD_NO_PART_SPEC_OVERLOAD)
        friend void swap (vector& __lhs, vector& __rhs) {
            __lhs.swap (__rhs);
        }
    #endif
    
    };
    
    #undef _Allocator
    to be continued in the next post, whole text exceeds 30k characters :)
  • 5. Re: Differnce between LibCstd and LibStlport
    902766 Newbie
    Currently Being Moderated
    +...continued from the previous post+

    and in <tt>vector.cc</tt> file with:
    // The body of this function is duplicated in src/vecbool.cpp and
    // further down in this file as well.
    #if !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) 
      template <class _Allocator>
      template<class _InputIter>
      void vector<bool, _Allocator >::insert 
    #else
      template<class _InputIter>
      void vector<bool, allocator<bool> >::insert 
    #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
      (iterator __it, _InputIter __first, _InputIter __last)
    
      {
        if (__first == __last) return;
        size_type __n = _DISTANCE (__first, __last, size_type);
        if (capacity() - size() >= __n)
        {
          copy_backward(__it, end(), _C_end + __n);
          copy(__first, __last, __it);
          _C_end += __n;
        }
        else
        {
          size_type __len = size() + (max)(size(), __n);
    
          unsigned int* __q = _C_bit_alloc(__len);
          iterator __i = copy(begin(), __it, iterator(__q, 0));
          __i = copy(__first, __last, __i);
          _C_end = copy(__it, end(), __i);
          _C_value_alloc_type (*this).
              deallocate((pointer)_C_begin._C_p,_C_bufend - _C_begin._C_p);
          _C_bufend = __q + (__len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
          _C_begin = iterator(__q, 0);
        }
      }
    
    #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
    
    // Duplicates of the following functions exist in src/stl/vecbool.cpp.
    // Which set is used depends on the availability of partial specialization.
    
      template <class _Allocator>
      void vector<bool,_Allocator >::flip ()
      {
        for (iterator __i = begin(); !(__i == end()); __i++)
          *__i = !(*__i);
      }
    
      template <class _Allocator>
      void vector<bool,_Allocator >::swap (reference __x, reference __y)
      {
        bool __tmp = __x; __x = __y; __y = __tmp;
      }
    
    
    template <class _Allocator>
    void vector<bool,_Allocator >::
    _C_insert (iterator __it, bool __x)
    {
        if (size () < capacity ()) {
    
            const iterator __end = _C_end;
    
            // move elements in the range [it, end) before the insert
            // one slot toward the end
            // i.e., copy [it, end) over [end - (end - it), end)
            // or, given N = distance(it, end) before the insert,
            //       copy [it, end) over [end - N, end)
            _RW_STD::copy_backward (__it, __end, ++_C_end);
    
            // overwrite the element at the given position
            *__it = __x;
        }
        else
        {
          size_type __len = size() ? 2 * size() : _RWSTD_WORD_BIT;
          unsigned int* __q = _C_bit_alloc(__len);
          iterator __i = _C_copy(begin(), __it, iterator(__q, 0));
          *__i++ = __x;
          _C_end = _C_copy(__it, end(), __i);
          _C_value_alloc_type (*this).
              deallocate((pointer)_C_begin._C_p,_C_bufend - _C_begin._C_p);
          _C_bufend = __q + (__len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
          _C_begin = iterator(__q, 0);
        }
    }
    
    
      template <class _Allocator>
      void vector<bool,_Allocator >::insert (iterator __it, size_type __n,
                                             const bool& __x)
      {
        if (__n == 0) return;
        if (capacity() - size() >= __n)
        {
          _C_copy_backward(__it, end(), _C_end + __n);
          _C_fill(__it, __it + __n, __x);
          _C_end += __n;
        }
        else
        {
          size_type __len = size() + (max)(size(), __n);
          unsigned int* __q = _C_bit_alloc(__len);
          iterator __i = _C_copy(begin(), __it, iterator(__q, 0));
          _C_fill_n(__i, __n, __x);
          _C_end = _C_copy(__it, end(), __i + __n);
          _C_value_alloc_type (*this).
              deallocate((pointer)_C_begin._C_p,_C_bufend - _C_begin._C_p);
          _C_bufend = __q + (__len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
          _C_begin = iterator(__q, 0);
        }
      }
    
    
      template <class _Allocator>
      void vector<bool,_Allocator >::resize (size_type __new_size, bool __c)
      {
        if (__new_size > size())
          insert(end(), __new_size - size(), __c);             
        else if (__new_size < size())
          erase(begin() + __new_size, end());
      }
    
    #endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC
    Note that the above code uses friend specifiaction in form
    friend class vector
    but compiles ok, while originally it fires compiler assertion.
    </ol>

    The changes above will help compile not only BOOST, the other library that benefits from enabling more standard features in libCstd is Qt (it needs <tt>iterator_traits</tt> and two-argument <tt>distance</tt>)

    I got into all that research because in our project we are forced to use libCstd shipped with the compiler as we utilize a library linked against it (unfortunatelly it is a commercial library, no sources available and simple replacement to stdcxx is impossible because stream classes are not binary compatible between stdcxx and libCstd).
    For those who do not care backward compatibility and look for standard conformance I however strongly suggest choosing <tt>-library=stdcxx4</tt> over <tt>-library=stlport4</tt>. The <tt>STLport</tt> implementation seems skewed (e.g. it moves everything to <tt>_STL</tt> namespace by making <tt>std</tt> a macro) and relies on some parts of original compiler headers (while stdcxx replaces everything, including <tt><typeinfo></tt> and <tt><exception></tt>).


    Finally, sorry for that long code fragments, I could not find "Attach a file" option on this forum :)
  • 6. Re: Differnce between LibCstd and LibStlport
    Steve_Clamage Pro
    Currently Being Moderated
    899763 wrote:
    One has three choices to unlock standard features in libCstd: ...
    Oracle does not support modifications to the headers provided with the compiler, nor do we support modifying, defining, or undefining configuration macros. If you run into problems, we can't help. The result of such modifications has never been tested. Since this library is based on a very early version of the library from Rogue Wave, the untested code is likely to have problems, particularly since we have made many modifications to the original Rogue Wave code.

    In addition, much of the library depends on support in the runtime library libCstd, which was built with unmodified headers and with additional source code that is not distributed with the compiler. I would in general expect that the declarations of some classes would not match, and that some functions would turn up missing. If your program using modified headers does link, there is a reasonable chance it will not run correctly.

    We have not attempted to find out which features in libCstd could be turned on without breaking compatibility. If you need better conformance to the C++ Standard but don't need compatibility with libCstd, we provide two alternative libraries: STLport and stdcxx. As poster 899763 notes, your best choice in this case would be to use one of the alternative libraries that we support.
  • 7. Re: Differnce between LibCstd and LibStlport
    902766 Newbie
    Currently Being Moderated
    Steve_Clamage wrote:

    Oracle does not support modifications to the headers provided with the compiler, nor do we support modifying, defining, or undefining configuration macros. If you run into problems, we can't help. The result of such modifications has never been tested. Since this library is based on a very early version of the library from Rogue Wave, the untested code is likely to have problems, particularly since we have made many modifications to the original Rogue Wave code.

    In addition, much of the library depends on support in the runtime library libCstd, which was built with unmodified headers and with additional source code that is not distributed with the compiler. I would in general expect that the declarations of some classes would not match, and that some functions would turn up missing. If your program using modified headers does link, there is a reasonable chance it will not run correctly.

    We have not attempted to find out which features in libCstd could be turned on without breaking compatibility. If you need better conformance to the C++ Standard but don't need compatibility with libCstd, we provide two alternative libraries: STLport and stdcxx. As poster 899763 notes, your best choice in this case would be to use one of the alternative libraries that we support.
    The third-party library we use only needs streams and string from libCstd and the modifications affect header-only classes (with the exception of <tt>vector<bool></tt> which is compiled into libCstd). I have compiled BOOST and tests that <tt>CC</tt> is able to compile did pass.

    We are going to make exhaustive testing as we understand that such a modified configuration is not supported by Oracle. We would undoubtedly use stdcxx if only the vendor of the third-party library had recompiled the code with the new library...

    And once more - in my opinion stdcxx is the best choice among the three available options
  • 8. Re: Differnce between LibCstd and LibStlport
    user12982757 Newbie
    Currently Being Moderated

    For the google cache:

     

    A HOWTO on compiling libstdcxx on Solaris with Studio 12.3:

    https://issues.apache.org/jira/browse/STDCXX-1074

     

     

     

    ta,

    Mark.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points