Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:02

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/json
0008 //
0009 
0010 #ifndef BOOST_JSON_IMPL_STRING_HPP
0011 #define BOOST_JSON_IMPL_STRING_HPP
0012 
0013 #include <utility>
0014 
0015 namespace boost {
0016 namespace json {
0017 
0018 string::
0019 string(
0020     detail::key_t const&,
0021     string_view s,
0022     storage_ptr sp)
0023     : sp_(std::move(sp))
0024     , impl_(detail::key_t{},
0025         s, sp_)
0026 {
0027 }
0028 
0029 string::
0030 string(
0031     detail::key_t const&,
0032     string_view s1,
0033     string_view s2,
0034     storage_ptr sp)
0035     : sp_(std::move(sp))
0036     , impl_(detail::key_t{},
0037         s1, s2, sp_)
0038 {
0039 }
0040 
0041 template<class InputIt, class>
0042 string::
0043 string(
0044     InputIt first,
0045     InputIt last,
0046     storage_ptr sp)
0047     : sp_(std::move(sp))
0048     , impl_(first, last, sp_,
0049         iter_cat<InputIt>{})
0050 {
0051 }
0052 
0053 template<class InputIt, class>
0054 string&
0055 string::
0056 assign(
0057     InputIt first,
0058     InputIt last)
0059 {
0060     assign(first, last,
0061         iter_cat<InputIt>{});
0062     return *this;
0063 }
0064 
0065 template<class InputIt, class>
0066 string&
0067 string::
0068 append(InputIt first, InputIt last)
0069 {
0070     append(first, last,
0071         iter_cat<InputIt>{});
0072     return *this;
0073 }
0074 
0075 // KRYSTIAN TODO: this can be done without copies when
0076 // reallocation is not needed, when the iterator is a
0077 // FowardIterator or better, as we can use std::distance
0078 template<class InputIt, class>
0079 auto
0080 string::
0081 insert(
0082     size_type pos,
0083     InputIt first,
0084     InputIt last) ->
0085         string&
0086 {
0087     struct cleanup
0088     {
0089         detail::string_impl& s;
0090         storage_ptr const& sp;
0091 
0092         ~cleanup()
0093         {
0094             s.destroy(sp);
0095         }
0096     };
0097 
0098     // We use the default storage because
0099     // the allocation is immediately freed.
0100     storage_ptr dsp;
0101     detail::string_impl tmp(
0102         first, last, dsp,
0103         iter_cat<InputIt>{});
0104     cleanup c{tmp, dsp};
0105     std::memcpy(
0106         impl_.insert_unchecked(pos, tmp.size(), sp_),
0107         tmp.data(),
0108         tmp.size());
0109     return *this;
0110 }
0111 
0112 // KRYSTIAN TODO: this can be done without copies when
0113 // reallocation is not needed, when the iterator is a
0114 // FowardIterator or better, as we can use std::distance
0115 template<class InputIt, class>
0116 auto
0117 string::
0118 replace(
0119     const_iterator first,
0120     const_iterator last,
0121     InputIt first2,
0122     InputIt last2) ->
0123         string&
0124 {
0125     struct cleanup
0126     {
0127         detail::string_impl& s;
0128         storage_ptr const& sp;
0129 
0130         ~cleanup()
0131         {
0132             s.destroy(sp);
0133         }
0134     };
0135 
0136     // We use the default storage because
0137     // the allocation is immediately freed.
0138     storage_ptr dsp;
0139     detail::string_impl tmp(
0140         first2, last2, dsp,
0141         iter_cat<InputIt>{});
0142     cleanup c{tmp, dsp};
0143     std::memcpy(
0144         impl_.replace_unchecked(
0145             first - begin(),
0146             last - first,
0147             tmp.size(),
0148             sp_),
0149         tmp.data(),
0150         tmp.size());
0151     return *this;
0152 }
0153 
0154 //----------------------------------------------------------
0155 
0156 template<class InputIt>
0157 void
0158 string::
0159 assign(
0160     InputIt first,
0161     InputIt last,
0162     std::random_access_iterator_tag)
0163 {
0164     auto dest = impl_.assign(static_cast<
0165         size_type>(last - first), sp_);
0166     while(first != last)
0167         *dest++ = *first++;
0168 }
0169 
0170 template<class InputIt>
0171 void
0172 string::
0173 assign(
0174     InputIt first,
0175     InputIt last,
0176     std::input_iterator_tag)
0177 {
0178     if(first == last)
0179     {
0180         impl_.term(0);
0181         return;
0182     }
0183     detail::string_impl tmp(
0184         first, last, sp_,
0185         std::input_iterator_tag{});
0186     impl_.destroy(sp_);
0187     impl_ = tmp;
0188 }
0189 
0190 template<class InputIt>
0191 void
0192 string::
0193 append(
0194     InputIt first,
0195     InputIt last,
0196     std::random_access_iterator_tag)
0197 {
0198 
0199     auto const n = static_cast<
0200         size_type>(last - first);
0201     char* out = impl_.append(n, sp_);
0202 #if defined(_MSC_VER) && _MSC_VER <= 1900
0203     while( first != last )
0204         *out++ = *first++;
0205 #else
0206     std::copy(first, last, out);
0207 #endif
0208 }
0209 
0210 template<class InputIt>
0211 void
0212 string::
0213 append(
0214     InputIt first,
0215     InputIt last,
0216     std::input_iterator_tag)
0217 {
0218     struct cleanup
0219     {
0220         detail::string_impl& s;
0221         storage_ptr const& sp;
0222 
0223         ~cleanup()
0224         {
0225             s.destroy(sp);
0226         }
0227     };
0228 
0229     // We use the default storage because
0230     // the allocation is immediately freed.
0231     storage_ptr dsp;
0232     detail::string_impl tmp(
0233         first, last, dsp,
0234         std::input_iterator_tag{});
0235     cleanup c{tmp, dsp};
0236     std::memcpy(
0237         impl_.append(tmp.size(), sp_),
0238         tmp.data(), tmp.size());
0239 }
0240 
0241 } // namespace json
0242 } // namespace boost
0243 
0244 #endif