Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // Debugging support implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2013 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file debug/functions.h
  26.  *  This file is a GNU debug extension to the Standard C++ Library.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
  30. #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
  31.  
  32. #include <bits/c++config.h>
  33. #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
  34.                                           // _Iter_base
  35. #include <bits/cpp_type_traits.h>         // for __is_integer
  36. #include <debug/formatter.h>
  37.  
  38. namespace __gnu_debug
  39. {
  40.   template<typename _Iterator, typename _Sequence>
  41.     class _Safe_iterator;
  42.  
  43.   // An arbitrary iterator pointer is not singular.
  44.   inline bool
  45.   __check_singular_aux(const void*) { return false; }
  46.  
  47.   // We may have an iterator that derives from _Safe_iterator_base but isn't
  48.   // a _Safe_iterator.
  49.   template<typename _Iterator>
  50.     inline bool
  51.     __check_singular(_Iterator& __x)
  52.     { return __check_singular_aux(&__x); }
  53.  
  54.   /** Non-NULL pointers are nonsingular. */
  55.   template<typename _Tp>
  56.     inline bool
  57.     __check_singular(const _Tp* __ptr)
  58.     { return __ptr == 0; }
  59.  
  60.   /** Safe iterators know if they are singular. */
  61.   template<typename _Iterator, typename _Sequence>
  62.     inline bool
  63.     __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
  64.     { return __x._M_singular(); }
  65.  
  66.   /** Assume that some arbitrary iterator is dereferenceable, because we
  67.       can't prove that it isn't. */
  68.   template<typename _Iterator>
  69.     inline bool
  70.     __check_dereferenceable(_Iterator&)
  71.     { return true; }
  72.  
  73.   /** Non-NULL pointers are dereferenceable. */
  74.   template<typename _Tp>
  75.     inline bool
  76.     __check_dereferenceable(const _Tp* __ptr)
  77.     { return __ptr; }
  78.  
  79.   /** Safe iterators know if they are singular. */
  80.   template<typename _Iterator, typename _Sequence>
  81.     inline bool
  82.     __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
  83.     { return __x._M_dereferenceable(); }
  84.  
  85.   /** If the distance between two random access iterators is
  86.    *  nonnegative, assume the range is valid.
  87.   */
  88.   template<typename _RandomAccessIterator>
  89.     inline bool
  90.     __valid_range_aux2(const _RandomAccessIterator& __first,
  91.                        const _RandomAccessIterator& __last,
  92.                        std::random_access_iterator_tag)
  93.     { return __last - __first >= 0; }
  94.  
  95.   /** Can't test for a valid range with input iterators, because
  96.    *  iteration may be destructive. So we just assume that the range
  97.    *  is valid.
  98.   */
  99.   template<typename _InputIterator>
  100.     inline bool
  101.     __valid_range_aux2(const _InputIterator&, const _InputIterator&,
  102.                        std::input_iterator_tag)
  103.     { return true; }
  104.  
  105.   /** We say that integral types for a valid range, and defer to other
  106.    *  routines to realize what to do with integral types instead of
  107.    *  iterators.
  108.   */
  109.   template<typename _Integral>
  110.     inline bool
  111.     __valid_range_aux(const _Integral&, const _Integral&, std::__true_type)
  112.     { return true; }
  113.  
  114.   /** We have iterators, so figure out what kind of iterators that are
  115.    *  to see if we can check the range ahead of time.
  116.   */
  117.   template<typename _InputIterator>
  118.     inline bool
  119.     __valid_range_aux(const _InputIterator& __first,
  120.                       const _InputIterator& __last, std::__false_type)
  121.   { return __valid_range_aux2(__first, __last,
  122.                               std::__iterator_category(__first)); }
  123.  
  124.   /** Don't know what these iterators are, or if they are even
  125.    *  iterators (we may get an integral type for InputIterator), so
  126.    *  see if they are integral and pass them on to the next phase
  127.    *  otherwise.
  128.   */
  129.   template<typename _InputIterator>
  130.     inline bool
  131.     __valid_range(const _InputIterator& __first, const _InputIterator& __last)
  132.     {
  133.       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
  134.       return __valid_range_aux(__first, __last, _Integral());
  135.     }
  136.  
  137.   /** Safe iterators know how to check if they form a valid range. */
  138.   template<typename _Iterator, typename _Sequence>
  139.     inline bool
  140.     __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
  141.                   const _Safe_iterator<_Iterator, _Sequence>& __last)
  142.     { return __first._M_valid_range(__last); }
  143.  
  144.   /** Safe local iterators know how to check if they form a valid range. */
  145.   template<typename _Iterator, typename _Sequence>
  146.     inline bool
  147.     __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first,
  148.                   const _Safe_local_iterator<_Iterator, _Sequence>& __last)
  149.     { return __first._M_valid_range(__last); }
  150.  
  151.   /* Checks that [first, last) is a valid range, and then returns
  152.    * __first. This routine is useful when we can't use a separate
  153.    * assertion statement because, e.g., we are in a constructor.
  154.   */
  155.   template<typename _InputIterator>
  156.     inline _InputIterator
  157.     __check_valid_range(const _InputIterator& __first,
  158.                         const _InputIterator& __last
  159.                         __attribute__((__unused__)))
  160.     {
  161.       __glibcxx_check_valid_range(__first, __last);
  162.       return __first;
  163.     }
  164.  
  165.   /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
  166.   template<typename _CharT, typename _Integer>
  167.     inline const _CharT*
  168.     __check_string(const _CharT* __s,
  169.                    const _Integer& __n __attribute__((__unused__)))
  170.     {
  171. #ifdef _GLIBCXX_DEBUG_PEDANTIC
  172.       __glibcxx_assert(__s != 0 || __n == 0);
  173. #endif
  174.       return __s;
  175.     }
  176.  
  177.   /** Checks that __s is non-NULL and then returns __s. */
  178.   template<typename _CharT>
  179.     inline const _CharT*
  180.     __check_string(const _CharT* __s)
  181.     {
  182. #ifdef _GLIBCXX_DEBUG_PEDANTIC
  183.       __glibcxx_assert(__s != 0);
  184. #endif
  185.       return __s;
  186.     }
  187.  
  188.   // Can't check if an input iterator sequence is sorted, because we
  189.   // can't step through the sequence.
  190.   template<typename _InputIterator>
  191.     inline bool
  192.     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
  193.                        std::input_iterator_tag)
  194.     { return true; }
  195.  
  196.   // Can verify if a forward iterator sequence is in fact sorted using
  197.   // std::__is_sorted
  198.   template<typename _ForwardIterator>
  199.     inline bool
  200.     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
  201.                        std::forward_iterator_tag)
  202.     {
  203.       if (__first == __last)
  204.         return true;
  205.  
  206.       _ForwardIterator __next = __first;
  207.       for (++__next; __next != __last; __first = __next, ++__next)
  208.         if (*__next < *__first)
  209.           return false;
  210.  
  211.       return true;
  212.     }
  213.  
  214.   // For performance reason, as the iterator range has been validated, check on
  215.   // random access safe iterators is done using the base iterator.
  216.   template<typename _Iterator, typename _Sequence>
  217.     inline bool
  218.     __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
  219.                        const _Safe_iterator<_Iterator, _Sequence>& __last,
  220.                        std::random_access_iterator_tag __tag)
  221.   { return __check_sorted_aux(__first.base(), __last.base(), __tag); }
  222.  
  223.   // Can't check if an input iterator sequence is sorted, because we can't step
  224.   // through the sequence.
  225.   template<typename _InputIterator, typename _Predicate>
  226.     inline bool
  227.     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
  228.                        _Predicate, std::input_iterator_tag)
  229.     { return true; }
  230.  
  231.   // Can verify if a forward iterator sequence is in fact sorted using
  232.   // std::__is_sorted
  233.   template<typename _ForwardIterator, typename _Predicate>
  234.     inline bool
  235.     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
  236.                        _Predicate __pred, std::forward_iterator_tag)
  237.     {
  238.       if (__first == __last)
  239.         return true;
  240.  
  241.       _ForwardIterator __next = __first;
  242.       for (++__next; __next != __last; __first = __next, ++__next)
  243.         if (__pred(*__next, *__first))
  244.           return false;
  245.  
  246.       return true;
  247.     }
  248.  
  249.   // For performance reason, as the iterator range has been validated, check on
  250.   // random access safe iterators is done using the base iterator.
  251.   template<typename _Iterator, typename _Sequence,
  252.            typename _Predicate>
  253.     inline bool
  254.     __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
  255.                        const _Safe_iterator<_Iterator, _Sequence>& __last,
  256.                        _Predicate __pred,
  257.                        std::random_access_iterator_tag __tag)
  258.   { return __check_sorted_aux(__first.base(), __last.base(), __pred, __tag); }
  259.  
  260.   // Determine if a sequence is sorted.
  261.   template<typename _InputIterator>
  262.     inline bool
  263.     __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
  264.     {
  265.       // Verify that the < operator for elements in the sequence is a
  266.       // StrictWeakOrdering by checking that it is irreflexive.
  267.       __glibcxx_assert(__first == __last || !(*__first < *__first));
  268.  
  269.       return __check_sorted_aux(__first, __last,
  270.                                 std::__iterator_category(__first));
  271.     }
  272.  
  273.   template<typename _InputIterator, typename _Predicate>
  274.     inline bool
  275.     __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
  276.                    _Predicate __pred)
  277.     {
  278.       // Verify that the predicate is StrictWeakOrdering by checking that it
  279.       // is irreflexive.
  280.       __glibcxx_assert(__first == __last || !__pred(*__first, *__first));
  281.  
  282.       return __check_sorted_aux(__first, __last, __pred,
  283.                                 std::__iterator_category(__first));
  284.     }
  285.  
  286.   template<typename _InputIterator>
  287.     inline bool
  288.     __check_sorted_set_aux(const _InputIterator& __first,
  289.                            const _InputIterator& __last,
  290.                            std::__true_type)
  291.     { return __check_sorted(__first, __last); }
  292.  
  293.   template<typename _InputIterator>
  294.     inline bool
  295.     __check_sorted_set_aux(const _InputIterator&,
  296.                            const _InputIterator&,
  297.                            std::__false_type)
  298.     { return true; }
  299.  
  300.   template<typename _InputIterator, typename _Predicate>
  301.     inline bool
  302.     __check_sorted_set_aux(const _InputIterator& __first,
  303.                            const _InputIterator& __last,
  304.                            _Predicate __pred, std::__true_type)
  305.     { return __check_sorted(__first, __last, __pred); }
  306.  
  307.   template<typename _InputIterator, typename _Predicate>
  308.     inline bool
  309.     __check_sorted_set_aux(const _InputIterator&,
  310.                            const _InputIterator&, _Predicate,
  311.                            std::__false_type)
  312.     { return true; }
  313.  
  314.   // ... special variant used in std::merge, std::includes, std::set_*.
  315.   template<typename _InputIterator1, typename _InputIterator2>
  316.     inline bool
  317.     __check_sorted_set(const _InputIterator1& __first,
  318.                        const _InputIterator1& __last,
  319.                        const _InputIterator2&)
  320.     {
  321.       typedef typename std::iterator_traits<_InputIterator1>::value_type
  322.         _ValueType1;
  323.       typedef typename std::iterator_traits<_InputIterator2>::value_type
  324.         _ValueType2;
  325.  
  326.       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
  327.         _SameType;
  328.       return __check_sorted_set_aux(__first, __last, _SameType());
  329.     }
  330.  
  331.   template<typename _InputIterator1, typename _InputIterator2,
  332.            typename _Predicate>
  333.     inline bool
  334.     __check_sorted_set(const _InputIterator1& __first,
  335.                        const _InputIterator1& __last,
  336.                        const _InputIterator2&, _Predicate __pred)
  337.     {
  338.       typedef typename std::iterator_traits<_InputIterator1>::value_type
  339.         _ValueType1;
  340.       typedef typename std::iterator_traits<_InputIterator2>::value_type
  341.         _ValueType2;
  342.  
  343.       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
  344.         _SameType;
  345.       return __check_sorted_set_aux(__first, __last, __pred, _SameType());
  346.    }
  347.  
  348.   template<typename _ForwardIterator, typename _Tp>
  349.     inline bool
  350.   __check_partitioned_lower_aux(_ForwardIterator __first,
  351.                                 _ForwardIterator __last, const _Tp& __value,
  352.                                 std::forward_iterator_tag)
  353.     {
  354.       while (__first != __last && *__first < __value)
  355.         ++__first;
  356.       if (__first != __last)
  357.         {
  358.           ++__first;
  359.           while (__first != __last && !(*__first < __value))
  360.             ++__first;
  361.         }
  362.       return __first == __last;
  363.     }
  364.  
  365.   // For performance reason, as the iterator range has been validated, check on
  366.   // random access safe iterators is done using the base iterator.
  367.   template<typename _Iterator, typename _Sequence, typename _Tp>
  368.     inline bool
  369.     __check_partitioned_lower_aux(
  370.                         const _Safe_iterator<_Iterator, _Sequence>& __first,
  371.                         const _Safe_iterator<_Iterator, _Sequence>& __last,
  372.                         const _Tp& __value,
  373.                         std::random_access_iterator_tag __tag)
  374.     {
  375.       return __check_partitioned_lower_aux(__first.base(), __last.base(),
  376.                                            __value, __tag);
  377.     }
  378.  
  379.   // _GLIBCXX_RESOLVE_LIB_DEFECTS
  380.   // 270. Binary search requirements overly strict
  381.   // Determine if a sequence is partitioned w.r.t. this element.
  382.   template<typename _ForwardIterator, typename _Tp>
  383.     inline bool
  384.     __check_partitioned_lower(_ForwardIterator __first,
  385.                               _ForwardIterator __last, const _Tp& __value)
  386.     {
  387.       return __check_partitioned_lower_aux(__first, __last, __value,
  388.                                            std::__iterator_category(__first));
  389.     }
  390.  
  391.   template<typename _ForwardIterator, typename _Tp>
  392.     inline bool
  393.     __check_partitioned_upper_aux(_ForwardIterator __first,
  394.                                   _ForwardIterator __last, const _Tp& __value,
  395.                                   std::forward_iterator_tag)
  396.     {
  397.       while (__first != __last && !(__value < *__first))
  398.         ++__first;
  399.       if (__first != __last)
  400.         {
  401.           ++__first;
  402.           while (__first != __last && __value < *__first)
  403.             ++__first;
  404.         }
  405.       return __first == __last;
  406.     }
  407.  
  408.   // For performance reason, as the iterator range has been validated, check on
  409.   // random access safe iterators is done using the base iterator.
  410.   template<typename _Iterator, typename _Sequence, typename _Tp>
  411.     inline bool
  412.     __check_partitioned_upper_aux(
  413.                         const _Safe_iterator<_Iterator, _Sequence>& __first,
  414.                         const _Safe_iterator<_Iterator, _Sequence>& __last,
  415.                         const _Tp& __value,
  416.                         std::random_access_iterator_tag __tag)
  417.     {
  418.       return __check_partitioned_upper_aux(__first.base(), __last.base(),
  419.                                            __value, __tag);
  420.     }
  421.  
  422.   template<typename _ForwardIterator, typename _Tp>
  423.     inline bool
  424.     __check_partitioned_upper(_ForwardIterator __first,
  425.                               _ForwardIterator __last, const _Tp& __value)
  426.     {
  427.       return __check_partitioned_upper_aux(__first, __last, __value,
  428.                                            std::__iterator_category(__first));
  429.     }
  430.  
  431.   template<typename _ForwardIterator, typename _Tp, typename _Pred>
  432.     inline bool
  433.     __check_partitioned_lower_aux(_ForwardIterator __first,
  434.                                   _ForwardIterator __last, const _Tp& __value,
  435.                                   _Pred __pred,
  436.                                   std::forward_iterator_tag)
  437.     {
  438.       while (__first != __last && bool(__pred(*__first, __value)))
  439.         ++__first;
  440.       if (__first != __last)
  441.         {
  442.           ++__first;
  443.           while (__first != __last && !bool(__pred(*__first, __value)))
  444.             ++__first;
  445.         }
  446.       return __first == __last;
  447.     }
  448.  
  449.   // For performance reason, as the iterator range has been validated, check on
  450.   // random access safe iterators is done using the base iterator.
  451.   template<typename _Iterator, typename _Sequence,
  452.            typename _Tp, typename _Pred>
  453.     inline bool
  454.     __check_partitioned_lower_aux(
  455.                         const _Safe_iterator<_Iterator, _Sequence>& __first,
  456.                         const _Safe_iterator<_Iterator, _Sequence>& __last,
  457.                         const _Tp& __value, _Pred __pred,
  458.                         std::random_access_iterator_tag __tag)
  459.     {
  460.       return __check_partitioned_lower_aux(__first.base(), __last.base(),
  461.                                            __value, __pred, __tag);
  462.     }
  463.  
  464.   // Determine if a sequence is partitioned w.r.t. this element.
  465.   template<typename _ForwardIterator, typename _Tp, typename _Pred>
  466.     inline bool
  467.     __check_partitioned_lower(_ForwardIterator __first,
  468.                               _ForwardIterator __last, const _Tp& __value,
  469.                               _Pred __pred)
  470.     {
  471.       return __check_partitioned_lower_aux(__first, __last, __value, __pred,
  472.                                            std::__iterator_category(__first));
  473.     }
  474.  
  475.   template<typename _ForwardIterator, typename _Tp, typename _Pred>
  476.     inline bool
  477.     __check_partitioned_upper_aux(_ForwardIterator __first,
  478.                                   _ForwardIterator __last, const _Tp& __value,
  479.                                   _Pred __pred,
  480.                                   std::forward_iterator_tag)
  481.     {
  482.       while (__first != __last && !bool(__pred(__value, *__first)))
  483.         ++__first;
  484.       if (__first != __last)
  485.         {
  486.           ++__first;
  487.           while (__first != __last && bool(__pred(__value, *__first)))
  488.             ++__first;
  489.         }
  490.       return __first == __last;
  491.     }
  492.  
  493.   // For performance reason, as the iterator range has been validated, check on
  494.   // random access safe iterators is done using the base iterator.
  495.   template<typename _Iterator, typename _Sequence,
  496.            typename _Tp, typename _Pred>
  497.     inline bool
  498.     __check_partitioned_upper_aux(
  499.                         const _Safe_iterator<_Iterator, _Sequence>& __first,
  500.                         const _Safe_iterator<_Iterator, _Sequence>& __last,
  501.                         const _Tp& __value, _Pred __pred,
  502.                         std::random_access_iterator_tag __tag)
  503.     {
  504.       return __check_partitioned_upper_aux(__first.base(), __last.base(),
  505.                                            __value, __pred, __tag);
  506.     }
  507.  
  508.   template<typename _ForwardIterator, typename _Tp, typename _Pred>
  509.     inline bool
  510.     __check_partitioned_upper(_ForwardIterator __first,
  511.                               _ForwardIterator __last, const _Tp& __value,
  512.                               _Pred __pred)
  513.     {
  514.       return __check_partitioned_upper_aux(__first, __last, __value, __pred,
  515.                                            std::__iterator_category(__first));
  516.     }
  517.  
  518.   // Helper struct to detect random access safe iterators.
  519.   template<typename _Iterator>
  520.     struct __is_safe_random_iterator
  521.     {
  522.       enum { __value = 0 };
  523.       typedef std::__false_type __type;
  524.     };
  525.  
  526.   template<typename _Iterator, typename _Sequence>
  527.     struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
  528.     : std::__are_same<std::random_access_iterator_tag,
  529.                       typename std::iterator_traits<_Iterator>::
  530.                       iterator_category>
  531.     { };
  532.  
  533.   template<typename _Iterator>
  534.     struct _Siter_base
  535.     : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
  536.     { };
  537.  
  538.   /** Helper function to extract base iterator of random access safe iterator
  539.       in order to reduce performance impact of debug mode.  Limited to random
  540.       access iterator because it is the only category for which it is possible
  541.       to check for correct iterators order in the __valid_range function
  542.       thanks to the < operator.
  543.   */
  544.   template<typename _Iterator>
  545.     inline typename _Siter_base<_Iterator>::iterator_type
  546.     __base(_Iterator __it)
  547.     { return _Siter_base<_Iterator>::_S_base(__it); }
  548. } // namespace __gnu_debug
  549.  
  550. #endif
  551.