LCOV - code coverage report
Current view: top level - DCPS - Util.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 65 23.1 %
Date: 2023-04-30 01:32:43 Functions: 11 110 10.0 %

          Line data    Source code
       1             : /*
       2             :  * Distributed under the OpenDDS License.
       3             :  * See: http://www.opendds.org/license.html
       4             :  */
       5             : 
       6             : #ifndef OPENDDS_DCPS_UTIL_H
       7             : #define OPENDDS_DCPS_UTIL_H
       8             : 
       9             : #include <ace/CDR_Base.h>
      10             : 
      11             : #include <cstring>
      12             : 
      13             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      14             : 
      15             : namespace OpenDDS {
      16             : namespace DCPS {
      17             : 
      18             : // bind reproduces the ACE_Hash_Map_Manager_Ex's bind behavior
      19             : template <typename Container, typename FirstType, typename SecondType>
      20           0 : int bind(
      21             :   Container& c,
      22             :   const FirstType& first,
      23             :   const SecondType& second)
      24             : {
      25           0 :   if (c.find(first) == c.end()) {
      26             :     typedef typename Container::value_type container_value_type;
      27             : 
      28           0 :     if (c.insert(container_value_type(first, second)).second) {
      29           0 :       return 0;
      30             :     }
      31             : 
      32           0 :     return -1;
      33             :   }
      34             : 
      35           0 :   return 1;
      36             : }
      37             : 
      38             : // unbind reproduces the ACE_Hash_Map_Manager_Ex's unbind behavior
      39             : template <typename Container>
      40           0 : int unbind(
      41             :   Container& c,
      42             :   const typename Container::key_type& k,
      43             :   typename Container::mapped_type& v)
      44             : {
      45           0 :   typename Container::const_iterator iter = c.find(k);
      46             : 
      47           0 :   if (iter != c.end()) {
      48           0 :     v = iter->second;
      49             : 
      50           0 :     if (c.erase(k) == 1) {
      51           0 :       return 0;
      52             :     }
      53             : 
      54           0 :     return -1;
      55             :   }
      56             : 
      57           0 :   return -1;
      58             : }
      59             : 
      60             : // unbind reproduces the ACE_Hash_Map_Manager_Ex's unbind behavior
      61             : template <typename Container>
      62           0 : int unbind(
      63             :   Container& c,
      64             :   const typename Container::key_type& k)
      65             : {
      66           0 :   typename Container::mapped_type v;
      67           0 :   return unbind(c, k, v);
      68           0 : }
      69             : 
      70             : template <typename Container, typename Key>
      71           0 : int find(
      72             :   Container& c,
      73             :   const Key& key,
      74             :   typename Container::mapped_type*& value)
      75             : {
      76             :   typename Container::iterator iter =
      77           0 :     c.find(key);
      78             : 
      79           0 :   if (iter == c.end()) {
      80           0 :     return -1;
      81             :   }
      82             : 
      83           0 :   value = &iter->second;
      84           0 :   return 0;
      85             : }
      86             : 
      87             : template <typename Container, typename Key>
      88           0 : int find(
      89             :   const Container& c,
      90             :   const Key& key,
      91             :   typename Container::mapped_type& value)
      92             : {
      93             :   typename Container::const_iterator iter =
      94           0 :     c.find(key);
      95             : 
      96           0 :   if (iter == c.end()) {
      97           0 :     return -1;
      98             :   }
      99             : 
     100           0 :   value = iter->second;
     101           0 :   return 0;
     102             : }
     103             : 
     104             : template <typename Container, typename ValueType>
     105           0 : int insert(
     106             :   Container& c,
     107             :   const ValueType& v)
     108             : {
     109           0 :   if (c.find(v) == c.end()) {
     110           0 :     if (c.insert(v).second) {
     111           0 :       return 0;
     112             :     }
     113             : 
     114           0 :     return -1;
     115             :   }
     116             : 
     117           0 :   return 1;
     118             : }
     119             : 
     120             : template <typename Container, typename ValueType>
     121           0 : int remove(
     122             :   Container& c,
     123             :   const ValueType& v)
     124             : {
     125           0 :   if (c.find(v) != c.end()) {
     126           0 :     if (c.erase(v) == 1) {
     127           0 :       return 0;
     128             :     }
     129             : 
     130           0 :     return -1;
     131             :   }
     132             : 
     133           0 :   return -1;
     134             : }
     135             : 
     136             : /// std::vector-style push_back() for CORBA Sequences
     137             : template <typename Seq>
     138        1759 : void push_back(Seq& seq, const typename Seq::value_type& val)
     139             : {
     140        1759 :   const ACE_CDR::ULong len = seq.length();
     141             :   // Grow by factor of 2 when length is a power of 2 in order to prevent every call to length(+1)
     142             :   // allocating a new buffer & copying previous results. The maximum is kept when length is reduced.
     143        1759 :   if (len && !(len & (len - 1))) {
     144         694 :     seq.length(2 * len);
     145             :   }
     146        1759 :   seq.length(len + 1);
     147        1759 :   seq[len] = val;
     148        1759 : }
     149             : 
     150             : template <typename Seq>
     151          33 : typename Seq::size_type grow(Seq& seq)
     152             : {
     153          33 :   const ACE_CDR::ULong len = seq.length();
     154             :   // Grow by factor of 2 when length is a power of 2 in order to prevent every call to length(+1)
     155             :   // allocating a new buffer & copying previous results. The maximum is kept when length is reduced.
     156          33 :   if (len && !(len & (len - 1))) {
     157          14 :     seq.length(2 * len);
     158             :   }
     159          33 :   seq.length(len + 1);
     160          33 :   return len + 1;
     161             : }
     162             : 
     163             : // Constructs a sorted intersect of the given two sorted ranges [a,aEnd) and [b,bEnd).
     164             : // (for pre-c++17 code for the similar effect of std::set_intersection in c++17)
     165             : template <typename InputIteratorA, typename InputIteratorB, typename OutputIterator>
     166             : OutputIterator intersect_sorted_ranges(InputIteratorA a, InputIteratorA aEnd,
     167             :                                        InputIteratorB b, InputIteratorB bEnd,
     168             :                                        OutputIterator intersect)
     169             : {
     170             :   while (a != aEnd && b != bEnd) {
     171             :     if (*a < *b) { ++a; }
     172             :     else if (*b < *a) { ++b; }
     173             :     else { *intersect++ = *a++; ++b; }
     174             :   }
     175             :   return intersect;
     176             : }
     177             : 
     178             : // Constructs a sorted intersect of the given two sorted ranges [a,aEnd) and [b,bEnd).
     179             : // (for pre-c++17 code for the similar effect of std::set_intersection in c++17)
     180             : template <typename InputIteratorA, typename InputIteratorB, typename OutputIterator, typename LessThan>
     181           0 : OutputIterator intersect_sorted_ranges(InputIteratorA a, InputIteratorA aEnd,
     182             :                                        InputIteratorB b, InputIteratorB bEnd,
     183             :                                        OutputIterator intersect, LessThan lessThan)
     184             : {
     185           0 :   while (a != aEnd && b != bEnd) {
     186           0 :     if (lessThan(*a, *b)) { ++a; }
     187           0 :     else if (lessThan(*b, *a)) { ++b; }
     188           0 :     else { *intersect++ = *a++; ++b; }
     189             :   }
     190           0 :   return intersect;
     191             : }
     192             : 
     193             : // Keeps the intersection of the two sorted collections in the first one,
     194             : // and returns whether an intersection exists between the two colloctions.
     195             : // Note:
     196             : // The generic scope of the first template parameter is narrowed down to std::set<T> because
     197             : // the pre-c++11 erase() may not work here with some collections (e.g. a sorted std::vector).
     198             : // The since-c++11 erase() works properly with both an std::set and a sorted std::vector.
     199             : template <typename SetA, typename SortedB, typename LessThan>
     200             : bool set_intersect(SetA& sA, const SortedB& sB, LessThan lessThan)
     201             : {
     202             :   typename SetA::iterator a = sA.begin();
     203             :   typename SortedB::const_iterator b = sB.begin();
     204             :   while (a != sA.end()) {
     205             :     if (b != sB.end()) {
     206             :       if (lessThan(*a, *b)) {
     207             :         sA.erase(a++);
     208             :       } else {
     209             :         if (!lessThan(*b, *a)) { ++a; }
     210             :         ++b;
     211             :       }
     212             :     } else {
     213             :       sA.erase(a, sA.end());
     214             :       break;
     215             :     }
     216             :   }
     217             :   return !sA.empty();
     218             : }
     219             : 
     220             : template <typename Type, size_t count>
     221           0 : size_t array_count(Type(&)[count])
     222             : {
     223           0 :   return count;
     224             : }
     225             : 
     226             : template <typename T>
     227        5026 : inline int mem_cmp(const T& a, const T& b)
     228             : {
     229        5026 :   return std::memcmp(&a, &b, sizeof(T));
     230             : }
     231             : 
     232             : } // namespace DCPS
     233             : } // namespace OpenDDS
     234             : 
     235             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     236             : 
     237             : #endif /* OPENDDS_DCPS_UTIL_H */

Generated by: LCOV version 1.16