Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:52:42

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_PARAMS_REF_HPP
0012 #define BOOST_URL_PARAMS_REF_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/ignore_case.hpp>
0016 #include <boost/url/params_base.hpp>
0017 #include <initializer_list>
0018 #include <iterator>
0019 
0020 namespace boost {
0021 namespace urls {
0022 
0023 #ifndef BOOST_URL_DOCS
0024 class url_base;
0025 class params_view;
0026 #endif
0027 
0028 /** A view representing query parameters in a URL
0029 
0030     Objects of this type are used to interpret
0031     the query parameters as a bidirectional view
0032     of key/value pairs.
0033     The view does not retain ownership of the
0034     elements and instead references the original
0035     url. The caller is responsible for ensuring
0036     that the lifetime of the referenced url
0037     extends until it is no longer referenced.
0038     The view is modifiable; calling non-const
0039     members causes changes to the referenced
0040     url.
0041 
0042     <br>
0043 
0044     Percent escapes in strings returned when
0045     dereferencing iterators are automatically
0046     decoded.
0047     Reserved characters in strings supplied
0048     to modifier functions are automatically
0049     percent-escaped.
0050 
0051     @par Example
0052     @code
0053     url u( "?first=John&last=Doe" );
0054 
0055     params_ref p = u.params();
0056     @endcode
0057 
0058     @par Iterator Invalidation
0059     Changes to the underlying character buffer
0060     can invalidate iterators which reference it.
0061     Modifications made through the container
0062     invalidate some or all iterators:
0063     <br>
0064 
0065     @li @ref append : Only `end()`.
0066 
0067     @li @ref assign, @ref clear,
0068         `operator=` : All elements.
0069 
0070     @li @ref erase : Erased elements and all
0071         elements after (including `end()`).
0072 
0073     @li @ref insert : All elements at or after
0074         the insertion point (including `end()`).
0075 
0076     @li @ref replace, @ref set : Modified
0077         elements and all elements
0078         after (including `end()`).
0079 */
0080 class BOOST_URL_DECL params_ref
0081     : public params_base
0082 {
0083     friend class url_base;
0084 
0085     url_base* u_ = nullptr;
0086 
0087     params_ref(
0088         url_base& u,
0089         encoding_opts opt) noexcept;
0090 
0091 public:
0092     //--------------------------------------------
0093     //
0094     // Special Members
0095     //
0096     //--------------------------------------------
0097 
0098     /** Constructor
0099 
0100         After construction, both views
0101         reference the same url. Ownership is not
0102         transferred; the caller is responsible
0103         for ensuring the lifetime of the url
0104         extends until it is no longer
0105         referenced.
0106 
0107         @par Postconditions
0108         @code
0109         &this->url() == &other.url()
0110         @endcode
0111 
0112         @par Complexity
0113         Constant.
0114 
0115         @par Exception Safety
0116         Throws nothing.
0117 
0118         @param other The other view.
0119     */
0120     params_ref(
0121         params_ref const& other) = default;
0122 
0123     /** Constructor
0124 
0125         After construction, both views will
0126         reference the same url but this
0127         instance will use the specified
0128         @ref encoding_opts when the values
0129         are decoded.
0130 
0131         Ownership is not transferred; the
0132         caller is responsible for ensuring
0133         the lifetime of the url extends
0134         until it is no longer referenced.
0135 
0136         @par Postconditions
0137         @code
0138         &this->url() == &other.url()
0139         @endcode
0140 
0141         @par Complexity
0142         Constant.
0143 
0144         @par Exception Safety
0145         Throws nothing.
0146 
0147         @param other The other view.
0148         @param opt The options for decoding. If
0149         this parameter is omitted, `space_as_plus`
0150         is used.
0151 
0152     */
0153     params_ref(
0154         params_ref const& other,
0155         encoding_opts opt) noexcept;
0156 
0157     /** Assignment
0158 
0159         The previous contents of this are
0160         replaced by the contents of `other.
0161 
0162         <br>
0163         All iterators are invalidated.
0164 
0165         @note
0166         The strings referenced by `other`
0167         must not come from the underlying url,
0168         or else the behavior is undefined.
0169 
0170         @par Effects
0171         @code
0172         this->assign( other.begin(), other.end() );
0173         @endcode
0174 
0175         @par Complexity
0176         Linear in `other.buffer().size()`.
0177 
0178         @par Exception Safety
0179         Strong guarantee.
0180         Calls to allocate may throw.
0181 
0182         @param other The params to assign.
0183         @return `*this`
0184     */
0185     params_ref&
0186     operator=(
0187         params_ref const& other);
0188 
0189     /** Assignment
0190 
0191         After assignment, the previous contents
0192         of the query parameters are replaced by
0193         the contents of the initializer-list.
0194 
0195         @par Preconditions
0196         None of character buffers referenced by
0197         `init` may overlap the character buffer of
0198         the underlying url, or else the behavior
0199         is undefined.
0200 
0201         @par Effects
0202         @code
0203         this->assign( init );
0204         @endcode
0205 
0206         @par Complexity
0207         Linear in `init.size()`.
0208 
0209         @par Exception Safety
0210         Strong guarantee.
0211         Calls to allocate may throw.
0212 
0213         @param init The list of params to assign.
0214         @return `*this`
0215     */
0216     params_ref&
0217     operator=(
0218         std::initializer_list<
0219             param_view> init);
0220 
0221     /** Conversion
0222 
0223         @return A view of the query parameters.
0224     */
0225     operator
0226     params_view() const noexcept;
0227 
0228     //--------------------------------------------
0229     //
0230     // Observers
0231     //
0232     //--------------------------------------------
0233 
0234     /** Return the referenced url
0235 
0236         This function returns the url referenced
0237         by the view.
0238 
0239         @par Example
0240         @code
0241         url u( "?key=value" );
0242 
0243         assert( &u.segments().url() == &u );
0244         @endcode
0245 
0246         @par Exception Safety
0247         @code
0248         Throws nothing.
0249         @endcode
0250 
0251         @return A reference to the url.
0252     */
0253     url_base&
0254     url() const noexcept
0255     {
0256         return *u_;
0257     }
0258 
0259     //--------------------------------------------
0260     //
0261     // Modifiers
0262     //
0263     //--------------------------------------------
0264 
0265     /** Clear the contents of the container
0266 
0267         <br>
0268         All iterators are invalidated.
0269 
0270         @par Effects
0271         @code
0272         this->url().remove_query();
0273         @endcode
0274 
0275         @par Postconditions
0276         @code
0277         this->empty() == true && this->url().has_query() == false
0278         @endcode
0279 
0280         @par Complexity
0281         Constant.
0282 
0283         @par Exception Safety
0284         Throws nothing.
0285     */
0286     void
0287     clear() noexcept;
0288 
0289     //--------------------------------------------
0290 
0291     /** Assign elements
0292 
0293         This function replaces the entire
0294         contents of the view with the params
0295         in the <em>initializer-list</em>.
0296 
0297         <br>
0298         All iterators are invalidated.
0299 
0300         @note
0301         The strings referenced by the inputs
0302         must not come from the underlying url,
0303         or else the behavior is undefined.
0304 
0305         @par Example
0306         @code
0307         url u;
0308 
0309         u.params().assign( {{ "first", "John" }, { "last", "Doe" }} );
0310         @endcode
0311 
0312         @par Complexity
0313         Linear in `init.size()`.
0314 
0315         @par Exception Safety
0316         Strong guarantee.
0317         Calls to allocate may throw.
0318 
0319         @param init The list of params to assign.
0320     */
0321     void
0322     assign(
0323         std::initializer_list<
0324             param_view> init);
0325 
0326     /** Assign elements
0327 
0328         This function replaces the entire
0329         contents of the view with the params
0330         in the range.
0331 
0332         <br>
0333         All iterators are invalidated.
0334 
0335         @note
0336         The strings referenced by the inputs
0337         must not come from the underlying url,
0338         or else the behavior is undefined.
0339 
0340         @par Mandates
0341         @code
0342         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0343         @endcode
0344 
0345         @par Complexity
0346         Linear in the size of the range.
0347 
0348         @par Exception Safety
0349         Strong guarantee.
0350         Calls to allocate may throw.
0351 
0352         @param first The first element to assign.
0353         @param last One past the last element to assign.
0354     */
0355     template<class FwdIt>
0356     void
0357     assign(FwdIt first, FwdIt last);
0358 
0359     //--------------------------------------------
0360 
0361     /** Append elements
0362 
0363         This function appends a param to the view.
0364 
0365         <br>
0366         The `end()` iterator is invalidated.
0367 
0368         @par Example
0369         @code
0370         url u;
0371 
0372         u.params().append( { "first", "John" } );
0373         @endcode
0374 
0375         @par Complexity
0376         Linear in `this->url().encoded_query().size()`.
0377 
0378         @par Exception Safety
0379         Strong guarantee.
0380         Calls to allocate may throw.
0381 
0382         @return An iterator to the new element.
0383 
0384         @param p The param to append.
0385     */
0386     iterator
0387     append(
0388         param_view const& p);
0389 
0390     /** Append elements
0391 
0392         This function appends the params in
0393         an <em>initializer-list</em> to the view.
0394 
0395         <br>
0396         The `end()` iterator is invalidated.
0397 
0398         @par Example
0399         @code
0400         url u;
0401 
0402         u.params().append({ { "first", "John" }, { "last", "Doe" } });
0403         @endcode
0404 
0405         @par Complexity
0406         Linear in `this->url().encoded_query().size()`.
0407 
0408         @par Exception Safety
0409         Strong guarantee.
0410         Calls to allocate may throw.
0411 
0412         @return An iterator to the first new element.
0413 
0414         @param init The list of params to append.
0415     */
0416     iterator
0417     append(
0418         std::initializer_list<
0419             param_view> init);
0420 
0421     /** Append elements
0422 
0423         This function appends a range of params
0424         to the view.
0425 
0426         <br>
0427         The `end()` iterator is invalidated.
0428 
0429         @note
0430         The strings referenced by the inputs
0431         must not come from the underlying url,
0432         or else the behavior is undefined.
0433 
0434         @par Mandates
0435         @code
0436         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0437         @endcode
0438 
0439         @par Complexity
0440         Linear in `this->url().encoded_query().size()`.
0441 
0442         @par Exception Safety
0443         Strong guarantee.
0444         Calls to allocate may throw.
0445 
0446         @param first The first element to append.
0447         @param last One past the last element to append.
0448         @return An iterator to the first new element.
0449     */
0450     template<class FwdIt>
0451     iterator
0452     append(
0453         FwdIt first, FwdIt last);
0454 
0455     //--------------------------------------------
0456 
0457     /** Insert elements
0458 
0459         This function inserts a param
0460         before the specified position.
0461 
0462         <br>
0463         All iterators that are equal to
0464         `before` or come after are invalidated.
0465 
0466         @par Complexity
0467         Linear in `this->url().encoded_query().size()`.
0468 
0469         @par Exception Safety
0470         Strong guarantee.
0471         Calls to allocate may throw.
0472 
0473         @return An iterator to the inserted
0474         element.
0475 
0476         @param before An iterator before which
0477         the param is inserted. This may
0478         be equal to `end()`.
0479 
0480         @param p The param to insert.
0481     */
0482     iterator
0483     insert(
0484         iterator before,
0485         param_view const& p);
0486 
0487     /** Insert elements
0488 
0489         This function inserts the params in
0490         an <em>initializer-list</em> before
0491         the specified position.
0492 
0493         <br>
0494         All iterators that are equal to
0495         `before` or come after are invalidated.
0496 
0497         @note
0498         The strings referenced by the inputs
0499         must not come from the underlying url,
0500         or else the behavior is undefined.
0501 
0502         @par Complexity
0503         Linear in `this->url().encoded_query().size()`.
0504 
0505         @par Exception Safety
0506         Strong guarantee.
0507         Calls to allocate may throw.
0508 
0509         @return An iterator to the first
0510         element inserted, or `before` if
0511         `init.size() == 0`.
0512 
0513         @param before An iterator before which
0514         the element is inserted. This may
0515         be equal to `end()`.
0516 
0517         @param init The list of params to insert.
0518     */
0519     iterator
0520     insert(
0521         iterator before,
0522         std::initializer_list<
0523             param_view> init);
0524 
0525     /** Insert elements
0526 
0527         This function inserts a range of
0528         params before the specified position.
0529 
0530         <br>
0531         All iterators that are equal to
0532         `before` or come after are invalidated.
0533 
0534         @note
0535         The strings referenced by the inputs
0536         must not come from the underlying url,
0537         or else the behavior is undefined.
0538 
0539         @par Mandates
0540         @code
0541         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0542         @endcode
0543 
0544         @par Complexity
0545         Linear in `this->url().encoded_query().size()`.
0546 
0547         @par Exception Safety
0548         Strong guarantee.
0549         Calls to allocate may throw.
0550 
0551         @return An iterator to the first
0552         element inserted, or `before` if
0553         `first == last`.
0554 
0555         @param before An iterator before which
0556         the element is inserted. This may
0557         be equal to `end()`.
0558         @param first The first element to insert.
0559         @param last One past the last element to insert.
0560         @return An iterator to the first element inserted, or `before` if `first == last`.
0561     */
0562     template<class FwdIt>
0563     iterator
0564     insert(
0565         iterator before,
0566         FwdIt first,
0567         FwdIt last);
0568 
0569     //--------------------------------------------
0570 
0571     /** Erase elements
0572 
0573         This function removes an element from
0574         the container.
0575 
0576         <br>
0577         All iterators that are equal to
0578         `pos` or come after are invalidated.
0579 
0580         @par Example
0581         @code
0582         url u( "?first=John&last=Doe" );
0583 
0584         params_ref::iterator it = u.params().erase( u.params().begin() );
0585 
0586         assert( u.encoded_query() == "last=Doe" );
0587         @endcode
0588 
0589         @par Complexity
0590         Linear in `this->url().encoded_query().size()`.
0591 
0592         @par Exception Safety
0593         Throws nothing.
0594 
0595         @return An iterator to one past
0596         the removed element.
0597 
0598         @param pos An iterator to the element.
0599     */
0600     iterator
0601     erase(iterator pos) noexcept;
0602 
0603     /** Erase elements
0604 
0605         This function removes a range of elements
0606         from the container.
0607 
0608         <br>
0609         All iterators that are equal to
0610         `first` or come after are invalidated.
0611 
0612         @par Complexity
0613         Linear in `this->url().encoded_query().size()`.
0614 
0615         @par Exception Safety
0616         Throws nothing.
0617 
0618         @param first The first element to remove.
0619         @param last One past the last element to remove.
0620         @return An iterator to one past the removed range.
0621     */
0622     iterator
0623     erase(
0624         iterator first,
0625         iterator last) noexcept;
0626 
0627     /** Erase elements
0628 
0629         <br>
0630         All iterators are invalidated.
0631 
0632         @par Postconditions
0633         @code
0634         this->count( key, ic ) == 0
0635         @endcode
0636 
0637         @par Complexity
0638         Linear in `this->url().encoded_query().size()`.
0639 
0640         @par Exception Safety
0641         Throws nothing.
0642 
0643         @return The number of elements removed
0644         from the container.
0645 
0646         @param key The key to match.
0647         By default, a case-sensitive
0648         comparison is used.
0649 
0650         @param ic An optional parameter. If
0651         the value @ref ignore_case is passed
0652         here, the comparison is
0653         case-insensitive.
0654     */
0655     std::size_t
0656     erase(
0657         core::string_view key,
0658         ignore_case_param ic = {}) noexcept;
0659 
0660     //--------------------------------------------
0661 
0662     /** Replace elements
0663 
0664         This function replaces the contents
0665         of the element at `pos` with the
0666         specified param.
0667 
0668         <br>
0669         All iterators that are equal to
0670         `pos` or come after are invalidated.
0671 
0672         @par Example
0673         @code
0674         url u( "?first=John&last=Doe" );
0675 
0676         u.params().replace( u.params().begin(), { "title", "Mr" });
0677 
0678         assert( u.encoded_query() == "title=Mr&last=Doe" );
0679         @endcode
0680 
0681         @par Complexity
0682         Linear in `this->url().encoded_query().size()`.
0683 
0684         @par Exception Safety
0685         Strong guarantee.
0686         Calls to allocate may throw.
0687 
0688         @return An iterator to the element.
0689 
0690         @param pos An iterator to the element.
0691 
0692         @param p The param to assign.
0693     */
0694     iterator
0695     replace(
0696         iterator pos,
0697         param_view const& p);
0698 
0699     /** Replace elements
0700 
0701         This function replaces a range of
0702         elements with the params in an
0703         <em>initializer-list</em>.
0704 
0705         <br>
0706         All iterators that are equal to
0707         `from` or come after are invalidated.
0708 
0709         @note
0710         The strings referenced by the inputs
0711         must not come from the underlying url,
0712         or else the behavior is undefined.
0713 
0714         @par Complexity
0715         Linear in `this->url().encoded_query().size()`.
0716 
0717         @par Exception Safety
0718         Strong guarantee.
0719         Calls to allocate may throw.
0720 
0721         @return An iterator to the first
0722         element inserted, or one past `to` if
0723         `init.size() == 0`.
0724 
0725         @param from,to The range of elements
0726         to replace.
0727 
0728         @param init The list of params to assign.
0729     */
0730     iterator
0731     replace(
0732         iterator from,
0733         iterator to,
0734         std::initializer_list<
0735             param_view> init);
0736 
0737     /** Replace elements
0738 
0739         This function replaces a range of
0740         elements with a range of params.
0741 
0742         <br>
0743         All iterators that are equal to
0744         `from` or come after are invalidated.
0745 
0746         @note
0747         The strings referenced by the inputs
0748         must not come from the underlying url,
0749         or else the behavior is undefined.
0750 
0751         @par Mandates
0752         @code
0753         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0754         @endcode
0755 
0756         @par Complexity
0757         Linear in `this->url().encoded_query().size()`.
0758 
0759         @par Exception Safety
0760         Strong guarantee.
0761         Calls to allocate may throw.
0762 
0763         @return An iterator to the first
0764         element inserted, or one past `to` if
0765         `first == last`.
0766 
0767         @param from The first element to replace.
0768         @param to One past the last element to replace.
0769         @param first The first element to insert.
0770         @param last One past the last element to insert.
0771         @return An iterator to the first element inserted, or one past `to` if `first == last`.
0772     */
0773     template<class FwdIt>
0774     iterator
0775     replace(
0776         iterator from,
0777         iterator to,
0778         FwdIt first,
0779         FwdIt last);
0780 
0781     //--------------------------------------------
0782 
0783     /** Remove the value on an element
0784 
0785         This function removes the value of
0786         an element at the specified position.
0787         After the call returns, `has_value`
0788         for the element is false.
0789 
0790         <br>
0791         All iterators that are equal to
0792         `pos` or come after are invalidated.
0793 
0794         @par Example
0795         @code
0796         url u( "?first=John&last=Doe" );
0797 
0798         u.params().unset( u.params().begin() );
0799 
0800         assert( u.encoded_query() == "first&last=Doe" );
0801         @endcode
0802 
0803         @par Complexity
0804         Linear in `this->url().encoded_query().size()`.
0805 
0806         @par Exception Safety
0807         Throws nothing.
0808 
0809         @return An iterator to the element.
0810 
0811         @param pos An iterator to the element.
0812     */
0813     iterator
0814     unset(
0815         iterator pos) noexcept;
0816 
0817     /** Set a value
0818 
0819         This function replaces the value of an
0820         element at the specified position.
0821 
0822         <br>
0823         All iterators that are equal to
0824         `pos` or come after are invalidated.
0825 
0826         @par Example
0827         @code
0828         url u( "?id=42&id=69" );
0829 
0830         u.params().set( u.params().begin(), "none" );
0831 
0832         assert( u.encoded_query() == "id=none&id=69" );
0833         @endcode
0834 
0835         @par Complexity
0836         Linear in `this->url().encoded_query().size()`.
0837 
0838         @par Exception Safety
0839         Strong guarantee.
0840         Calls to allocate may throw.
0841 
0842         @return An iterator to the element.
0843 
0844         @param pos An iterator to the element.
0845 
0846         @param value The value to assign. The
0847         empty string still counts as a value.
0848         That is, `has_value` for the element
0849         is true.
0850     */
0851     iterator
0852     set(
0853         iterator pos,
0854         core::string_view value);
0855 
0856     /** Set a value
0857 
0858         This function performs one of two
0859         actions depending on the value of
0860         `this->contains( key, ic )`.
0861 
0862         @li If key is contained in the view
0863         then one of the matching elements has
0864         its value changed to the specified value.
0865         The remaining elements with a matching
0866         key are erased. Otherwise,
0867 
0868         @li If `key` is not contained in the
0869         view, then the function apppends the
0870         param `{ key, value }`.
0871 
0872         <br>
0873         All iterators are invalidated.
0874 
0875         @par Example
0876         @code
0877         url u( "?id=42&id=69" );
0878 
0879         u.params().set( "id", "none" );
0880 
0881         assert( u.params().count( "id" ) == 1 );
0882         @endcode
0883 
0884         @par Postconditions
0885         @code
0886         this->count( key, ic ) == 1 && this->find( key, ic )->value == value
0887         @endcode
0888 
0889         @par Complexity
0890         Linear in `this->url().encoded_query().size()`.
0891 
0892         @par Exception Safety
0893         Strong guarantee.
0894         Calls to allocate may throw.
0895 
0896         @return An iterator to the appended
0897         or modified element.
0898 
0899         @param key The key to match.
0900         By default, a case-sensitive
0901         comparison is used.
0902 
0903         @param value The value to assign. The
0904         empty string still counts as a value.
0905         That is, `has_value` for the element
0906         is true.
0907 
0908         @param ic An optional parameter. If
0909         the value @ref ignore_case is passed
0910         here, the comparison is
0911         case-insensitive.
0912     */
0913     iterator
0914     set(
0915         core::string_view key,
0916         core::string_view value,
0917         ignore_case_param ic = {});
0918 
0919     //--------------------------------------------
0920 
0921 private:
0922     template<class FwdIt>
0923     void
0924     assign(FwdIt first, FwdIt last,
0925         std::forward_iterator_tag);
0926 
0927     // Doxygen cannot render ` = delete`
0928     template<class FwdIt>
0929     void
0930     assign(FwdIt first, FwdIt last,
0931         std::input_iterator_tag) = delete;
0932 
0933     template<class FwdIt>
0934     iterator
0935     insert(
0936         iterator before,
0937         FwdIt first,
0938         FwdIt last,
0939         std::forward_iterator_tag);
0940 
0941     // Doxygen cannot render ` = delete`
0942     template<class FwdIt>
0943     iterator
0944     insert(
0945         iterator before,
0946         FwdIt first,
0947         FwdIt last,
0948         std::input_iterator_tag) = delete;
0949 };
0950 
0951 } // urls
0952 } // boost
0953 
0954 // This is in <boost/url/url_base.hpp>
0955 //
0956 // #include <boost/url/impl/params_ref.hpp>
0957 
0958 #endif