Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:29

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     */
0184     params_ref&
0185     operator=(
0186         params_ref const& other);
0187 
0188     /** Assignment
0189 
0190         After assignment, the previous contents
0191         of the query parameters are replaced by
0192         the contents of the initializer-list.
0193 
0194         @par Preconditions
0195         None of character buffers referenced by
0196         `init` may overlap the character buffer of
0197         the underlying url, or else the behavior
0198         is undefined.
0199 
0200         @par Effects
0201         @code
0202         this->assign( init );
0203         @endcode
0204 
0205         @par Complexity
0206         Linear in `init.size()`.
0207 
0208         @par Exception Safety
0209         Strong guarantee.
0210         Calls to allocate may throw.
0211 
0212         @param init The list of params to assign.
0213     */
0214     params_ref&
0215     operator=(
0216         std::initializer_list<
0217             param_view> init);
0218 
0219     /** Conversion
0220     */
0221     operator
0222     params_view() const noexcept;
0223 
0224     //--------------------------------------------
0225     //
0226     // Observers
0227     //
0228     //--------------------------------------------
0229 
0230     /** Return the referenced url
0231 
0232         This function returns the url referenced
0233         by the view.
0234 
0235         @par Example
0236         @code
0237         url u( "?key=value" );
0238 
0239         assert( &u.segments().url() == &u );
0240         @endcode
0241 
0242         @par Exception Safety
0243         @code
0244         Throws nothing.
0245         @endcode
0246     */
0247     url_base&
0248     url() const noexcept
0249     {
0250         return *u_;
0251     }
0252 
0253     //--------------------------------------------
0254     //
0255     // Modifiers
0256     //
0257     //--------------------------------------------
0258 
0259     /** Clear the contents of the container
0260 
0261         <br>
0262         All iterators are invalidated.
0263 
0264         @par Effects
0265         @code
0266         this->url().remove_query();
0267         @endcode
0268 
0269         @par Postconditions
0270         @code
0271         this->empty() == true && this->url().has_query() == false
0272         @endcode
0273 
0274         @par Complexity
0275         Constant.
0276 
0277         @par Exception Safety
0278         Throws nothing.
0279     */
0280     void
0281     clear() noexcept;
0282 
0283     //--------------------------------------------
0284 
0285     /** Assign elements
0286 
0287         This function replaces the entire
0288         contents of the view with the params
0289         in the <em>initializer-list</em>.
0290 
0291         <br>
0292         All iterators are invalidated.
0293 
0294         @note
0295         The strings referenced by the inputs
0296         must not come from the underlying url,
0297         or else the behavior is undefined.
0298 
0299         @par Example
0300         @code
0301         url u;
0302 
0303         u.params().assign( {{ "first", "John" }, { "last", "Doe" }} );
0304         @endcode
0305 
0306         @par Complexity
0307         Linear in `init.size()`.
0308 
0309         @par Exception Safety
0310         Strong guarantee.
0311         Calls to allocate may throw.
0312 
0313         @param init The list of params to assign.
0314     */
0315     void
0316     assign(
0317         std::initializer_list<
0318             param_view> init);
0319 
0320     /** Assign elements
0321 
0322         This function replaces the entire
0323         contents of the view with the params
0324         in the range.
0325 
0326         <br>
0327         All iterators are invalidated.
0328 
0329         @note
0330         The strings referenced by the inputs
0331         must not come from the underlying url,
0332         or else the behavior is undefined.
0333 
0334         @par Mandates
0335         @code
0336         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0337         @endcode
0338 
0339         @par Complexity
0340         Linear in the size of the range.
0341 
0342         @par Exception Safety
0343         Strong guarantee.
0344         Calls to allocate may throw.
0345 
0346         @param first, last The range of params
0347         to assign.
0348     */
0349     template<class FwdIt>
0350     void
0351     assign(FwdIt first, FwdIt last);
0352 
0353     //--------------------------------------------
0354 
0355     /** Append elements
0356 
0357         This function appends a param to the view.
0358 
0359         <br>
0360         The `end()` iterator is invalidated.
0361 
0362         @par Example
0363         @code
0364         url u;
0365 
0366         u.params().append( { "first", "John" } );
0367         @endcode
0368 
0369         @par Complexity
0370         Linear in `this->url().encoded_query().size()`.
0371 
0372         @par Exception Safety
0373         Strong guarantee.
0374         Calls to allocate may throw.
0375 
0376         @return An iterator to the new element.
0377 
0378         @param p The param to append.
0379     */
0380     iterator
0381     append(
0382         param_view const& p);
0383 
0384     /** Append elements
0385 
0386         This function appends the params in
0387         an <em>initializer-list</em> to the view.
0388 
0389         <br>
0390         The `end()` iterator is invalidated.
0391 
0392         @par Example
0393         @code
0394         url u;
0395 
0396         u.params().append({ { "first", "John" }, { "last", "Doe" } });
0397         @endcode
0398 
0399         @par Complexity
0400         Linear in `this->url().encoded_query().size()`.
0401 
0402         @par Exception Safety
0403         Strong guarantee.
0404         Calls to allocate may throw.
0405 
0406         @return An iterator to the first new element.
0407 
0408         @param init The list of params to append.
0409     */
0410     iterator
0411     append(
0412         std::initializer_list<
0413             param_view> init);
0414 
0415     /** Append elements
0416 
0417         This function appends a range of params
0418         to the view.
0419 
0420         <br>
0421         The `end()` iterator is invalidated.
0422 
0423         @note
0424         The strings referenced by the inputs
0425         must not come from the underlying url,
0426         or else the behavior is undefined.
0427 
0428         @par Mandates
0429         @code
0430         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0431         @endcode
0432 
0433         @par Complexity
0434         Linear in `this->url().encoded_query().size()`.
0435 
0436         @par Exception Safety
0437         Strong guarantee.
0438         Calls to allocate may throw.
0439 
0440         @return An iterator to the first new element.
0441 
0442         @param first, last The range of params
0443         to append.
0444     */
0445     template<class FwdIt>
0446     iterator
0447     append(
0448         FwdIt first, FwdIt last);
0449 
0450     //--------------------------------------------
0451 
0452     /** Insert elements
0453 
0454         This function inserts a param
0455         before the specified position.
0456 
0457         <br>
0458         All iterators that are equal to
0459         `before` or come after are invalidated.
0460 
0461         @par Complexity
0462         Linear in `this->url().encoded_query().size()`.
0463 
0464         @par Exception Safety
0465         Strong guarantee.
0466         Calls to allocate may throw.
0467 
0468         @return An iterator to the inserted
0469         element.
0470 
0471         @param before An iterator before which
0472         the param is inserted. This may
0473         be equal to `end()`.
0474 
0475         @param p The param to insert.
0476     */
0477     iterator
0478     insert(
0479         iterator before,
0480         param_view const& p);
0481 
0482     /** Insert elements
0483 
0484         This function inserts the params in
0485         an <em>initializer-list</em> before
0486         the specified position.
0487 
0488         <br>
0489         All iterators that are equal to
0490         `before` or come after are invalidated.
0491 
0492         @note
0493         The strings referenced by the inputs
0494         must not come from the underlying url,
0495         or else the behavior is undefined.
0496 
0497         @par Complexity
0498         Linear in `this->url().encoded_query().size()`.
0499 
0500         @par Exception Safety
0501         Strong guarantee.
0502         Calls to allocate may throw.
0503 
0504         @return An iterator to the first
0505         element inserted, or `before` if
0506         `init.size() == 0`.
0507 
0508         @param before An iterator before which
0509         the element is inserted. This may
0510         be equal to `end()`.
0511 
0512         @param init The list of params to insert.
0513     */
0514     iterator
0515     insert(
0516         iterator before,
0517         std::initializer_list<
0518             param_view> init);
0519 
0520     /** Insert elements
0521 
0522         This function inserts a range of
0523         params before the specified position.
0524 
0525         <br>
0526         All iterators that are equal to
0527         `before` or come after are invalidated.
0528 
0529         @note
0530         The strings referenced by the inputs
0531         must not come from the underlying url,
0532         or else the behavior is undefined.
0533 
0534         @par Mandates
0535         @code
0536         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0537         @endcode
0538 
0539         @par Complexity
0540         Linear in `this->url().encoded_query().size()`.
0541 
0542         @par Exception Safety
0543         Strong guarantee.
0544         Calls to allocate may throw.
0545 
0546         @return An iterator to the first
0547         element inserted, or `before` if
0548         `first == last`.
0549 
0550         @param before An iterator before which
0551         the element is inserted. This may
0552         be equal to `end()`.
0553 
0554         @param first, last The range of params
0555         to insert.
0556     */
0557     template<class FwdIt>
0558     iterator
0559     insert(
0560         iterator before,
0561         FwdIt first,
0562         FwdIt last);
0563 
0564     //--------------------------------------------
0565 
0566     /** Erase elements
0567 
0568         This function removes an element from
0569         the container.
0570 
0571         <br>
0572         All iterators that are equal to
0573         `pos` or come after are invalidated.
0574 
0575         @par Example
0576         @code
0577         url u( "?first=John&last=Doe" );
0578 
0579         params_ref::iterator it = u.params().erase( u.params().begin() );
0580 
0581         assert( u.encoded_query() == "last=Doe" );
0582         @endcode
0583 
0584         @par Complexity
0585         Linear in `this->url().encoded_query().size()`.
0586 
0587         @par Exception Safety
0588         Throws nothing.
0589 
0590         @return An iterator to one past
0591         the removed element.
0592 
0593         @param pos An iterator to the element.
0594     */
0595     iterator
0596     erase(iterator pos) noexcept;
0597 
0598     /** Erase elements
0599 
0600         This function removes a range of elements
0601         from the container.
0602 
0603         <br>
0604         All iterators that are equal to
0605         `first` or come after are invalidated.
0606 
0607         @par Complexity
0608         Linear in `this->url().encoded_query().size()`.
0609 
0610         @par Exception Safety
0611         Throws nothing.
0612 
0613         @return An iterator to one past
0614         the removed range.
0615 
0616         @param first, last The range of
0617         elements to erase.
0618     */
0619     iterator
0620     erase(
0621         iterator first,
0622         iterator last) noexcept;
0623 
0624     /** Erase elements
0625 
0626         <br>
0627         All iterators are invalidated.
0628 
0629         @par Postconditions
0630         @code
0631         this->count( key, ic ) == 0
0632         @endcode
0633 
0634         @par Complexity
0635         Linear in `this->url().encoded_query().size()`.
0636 
0637         @par Exception Safety
0638         Throws nothing.
0639 
0640         @return The number of elements removed
0641         from the container.
0642 
0643         @param key The key to match.
0644         By default, a case-sensitive
0645         comparison is used.
0646 
0647         @param ic An optional parameter. If
0648         the value @ref ignore_case is passed
0649         here, the comparison is
0650         case-insensitive.
0651     */
0652     std::size_t
0653     erase(
0654         core::string_view key,
0655         ignore_case_param ic = {}) noexcept;
0656 
0657     //--------------------------------------------
0658 
0659     /** Replace elements
0660 
0661         This function replaces the contents
0662         of the element at `pos` with the
0663         specified param.
0664 
0665         <br>
0666         All iterators that are equal to
0667         `pos` or come after are invalidated.
0668 
0669         @par Example
0670         @code
0671         url u( "?first=John&last=Doe" );
0672 
0673         u.params().replace( u.params().begin(), { "title", "Mr" });
0674 
0675         assert( u.encoded_query() == "title=Mr&last=Doe" );
0676         @endcode
0677 
0678         @par Complexity
0679         Linear in `this->url().encoded_query().size()`.
0680 
0681         @par Exception Safety
0682         Strong guarantee.
0683         Calls to allocate may throw.
0684 
0685         @return An iterator to the element.
0686 
0687         @param pos An iterator to the element.
0688 
0689         @param p The param to assign.
0690     */
0691     iterator
0692     replace(
0693         iterator pos,
0694         param_view const& p);
0695 
0696     /** Replace elements
0697 
0698         This function replaces a range of
0699         elements with the params in an
0700         <em>initializer-list</em>.
0701 
0702         <br>
0703         All iterators that are equal to
0704         `from` or come after are invalidated.
0705 
0706         @note
0707         The strings referenced by the inputs
0708         must not come from the underlying url,
0709         or else the behavior is undefined.
0710 
0711         @par Complexity
0712         Linear in `this->url().encoded_query().size()`.
0713 
0714         @par Exception Safety
0715         Strong guarantee.
0716         Calls to allocate may throw.
0717 
0718         @return An iterator to the first
0719         element inserted, or one past `to` if
0720         `init.size() == 0`.
0721 
0722         @param from,to The range of elements
0723         to replace.
0724 
0725         @param init The list of params to assign.
0726     */
0727     iterator
0728     replace(
0729         iterator from,
0730         iterator to,
0731         std::initializer_list<
0732             param_view> init);
0733 
0734     /** Replace elements
0735 
0736         This function replaces a range of
0737         elements with a range of params.
0738 
0739         <br>
0740         All iterators that are equal to
0741         `from` or come after are invalidated.
0742 
0743         @note
0744         The strings referenced by the inputs
0745         must not come from the underlying url,
0746         or else the behavior is undefined.
0747 
0748         @par Mandates
0749         @code
0750         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
0751         @endcode
0752 
0753         @par Complexity
0754         Linear in `this->url().encoded_query().size()`.
0755 
0756         @par Exception Safety
0757         Strong guarantee.
0758         Calls to allocate may throw.
0759 
0760         @return An iterator to the first
0761         element inserted, or one past `to` if
0762         `first == last`.
0763 
0764         @param from,to The range of elements to
0765         replace.
0766 
0767         @param first, last The range of params
0768         to assign.
0769     */
0770     template<class FwdIt>
0771     iterator
0772     replace(
0773         iterator from,
0774         iterator to,
0775         FwdIt first,
0776         FwdIt last);
0777 
0778     //--------------------------------------------
0779 
0780     /** Remove the value on an element
0781 
0782         This function removes the value of
0783         an element at the specified position.
0784         After the call returns, `has_value`
0785         for the element is false.
0786 
0787         <br>
0788         All iterators that are equal to
0789         `pos` or come after are invalidated.
0790 
0791         @par Example
0792         @code
0793         url u( "?first=John&last=Doe" );
0794 
0795         u.params().unset( u.params().begin() );
0796 
0797         assert( u.encoded_query() == "first&last=Doe" );
0798         @endcode
0799 
0800         @par Complexity
0801         Linear in `this->url().encoded_query().size()`.
0802 
0803         @par Exception Safety
0804         Throws nothing.
0805 
0806         @return An iterator to the element.
0807 
0808         @param pos An iterator to the element.
0809     */
0810     iterator
0811     unset(
0812         iterator pos) noexcept;
0813 
0814     /** Set a value
0815 
0816         This function replaces the value of an
0817         element at the specified position.
0818 
0819         <br>
0820         All iterators that are equal to
0821         `pos` or come after are invalidated.
0822 
0823         @par Example
0824         @code
0825         url u( "?id=42&id=69" );
0826 
0827         u.params().set( u.params().begin(), "none" );
0828 
0829         assert( u.encoded_query() == "id=none&id=69" );
0830         @endcode
0831 
0832         @par Complexity
0833         Linear in `this->url().encoded_query().size()`.
0834 
0835         @par Exception Safety
0836         Strong guarantee.
0837         Calls to allocate may throw.
0838 
0839         @return An iterator to the element.
0840 
0841         @param pos An iterator to the element.
0842 
0843         @param value The value to assign. The
0844         empty string still counts as a value.
0845         That is, `has_value` for the element
0846         is true.
0847     */
0848     iterator
0849     set(
0850         iterator pos,
0851         core::string_view value);
0852 
0853     /** Set a value
0854 
0855         This function performs one of two
0856         actions depending on the value of
0857         `this->contains( key, ic )`.
0858 
0859         @li If key is contained in the view
0860         then one of the matching elements has
0861         its value changed to the specified value.
0862         The remaining elements with a matching
0863         key are erased. Otherwise,
0864 
0865         @li If `key` is not contained in the
0866         view, then the function apppends the
0867         param `{ key, value }`.
0868 
0869         <br>
0870         All iterators are invalidated.
0871 
0872         @par Example
0873         @code
0874         url u( "?id=42&id=69" );
0875 
0876         u.params().set( "id", "none" );
0877 
0878         assert( u.params().count( "id" ) == 1 );
0879         @endcode
0880 
0881         @par Postconditions
0882         @code
0883         this->count( key, ic ) == 1 && this->find( key, ic )->value == value
0884         @endcode
0885 
0886         @par Complexity
0887         Linear in `this->url().encoded_query().size()`.
0888 
0889         @par Exception Safety
0890         Strong guarantee.
0891         Calls to allocate may throw.
0892 
0893         @return An iterator to the appended
0894         or modified element.
0895 
0896         @param key The key to match.
0897         By default, a case-sensitive
0898         comparison is used.
0899 
0900         @param value The value to assign. The
0901         empty string still counts as a value.
0902         That is, `has_value` for the element
0903         is true.
0904 
0905         @param ic An optional parameter. If
0906         the value @ref ignore_case is passed
0907         here, the comparison is
0908         case-insensitive.
0909     */
0910     iterator
0911     set(
0912         core::string_view key,
0913         core::string_view value,
0914         ignore_case_param ic = {});
0915 
0916     //--------------------------------------------
0917 
0918 private:
0919     detail::params_iter_impl
0920     find_impl(
0921         detail::params_iter_impl,
0922         core::string_view,
0923         ignore_case_param) const noexcept;
0924 
0925     detail::params_iter_impl
0926     find_last_impl(
0927         detail::params_iter_impl,
0928         core::string_view,
0929         ignore_case_param) const noexcept;
0930 
0931     template<class FwdIt>
0932     void
0933     assign(FwdIt first, FwdIt last,
0934         std::forward_iterator_tag);
0935 
0936     // Doxygen cannot render ` = delete`
0937     template<class FwdIt>
0938     void
0939     assign(FwdIt first, FwdIt last,
0940         std::input_iterator_tag) = delete;
0941 
0942     template<class FwdIt>
0943     iterator
0944     insert(
0945         iterator before,
0946         FwdIt first,
0947         FwdIt last,
0948         std::forward_iterator_tag);
0949 
0950     // Doxygen cannot render ` = delete`
0951     template<class FwdIt>
0952     iterator
0953     insert(
0954         iterator before,
0955         FwdIt first,
0956         FwdIt last,
0957         std::input_iterator_tag) = delete;
0958 };
0959 
0960 } // urls
0961 } // boost
0962 
0963 // This is in <boost/url/url_base.hpp>
0964 //
0965 // #include <boost/url/impl/params_ref.hpp>
0966 
0967 #endif