Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:57

0001 #ifndef ParameterSet_split_h
0002 #define ParameterSet_split_h
0003 
0004 // ----------------------------------------------------------------------
0005 // definition of split() and related templates
0006 // ----------------------------------------------------------------------
0007 
0008 // ----------------------------------------------------------------------
0009 // prolog
0010 
0011 // ----------------------------------------------------------------------
0012 // prerequisite source files and headers
0013 
0014 #include <string_view>
0015 
0016 // ----------------------------------------------------------------------
0017 // contents
0018 
0019 namespace edm {
0020 
0021   template <class FwdIter>
0022   FwdIter contextual_find(FwdIter b, FwdIter e, char first, char sep, char last);
0023 
0024   template <class FwdIter>
0025   FwdIter contextual_find_not(FwdIter b, FwdIter e, char first, char sep, char last);
0026 
0027   template <class OutIter>
0028   bool split(OutIter result, std::string_view string_to_split, char first, char sep, char last);
0029 
0030   template <typename FUNC>
0031   bool split(std::string_view string_to_split, char first, char sep, char last, FUNC f);
0032 }  // namespace edm
0033 
0034 // ----------------------------------------------------------------------
0035 // contextual_find
0036 
0037 template <class FwdIter>
0038 FwdIter edm::contextual_find(FwdIter b, FwdIter e, char first, char sep, char last) {
0039   for (int nested = 0; b != e; ++b) {
0040     if (*b == first)
0041       ++nested;
0042     else if (*b == last)
0043       --nested;
0044     else if (*b == sep && nested == 0)
0045       return b;
0046   }
0047 
0048   return e;
0049 
0050 }  // contextual_find()
0051 
0052 // ----------------------------------------------------------------------
0053 // contextual_find_not
0054 
0055 template <class FwdIter>
0056 FwdIter edm::contextual_find_not(FwdIter b, FwdIter e, char /* first */, char sep, char /* last */) {
0057   for (; b != e; ++b) {
0058     if (*b != sep)
0059       return b;
0060   }
0061 
0062   return e;
0063 
0064 }  // contextual_find_not()
0065 
0066 // ----------------------------------------------------------------------
0067 // split()
0068 
0069 template <class OutIter>
0070 bool edm::split(OutIter dest, std::string_view s, char first, char sep, char last) {
0071   using str_c_iter = std::string_view::const_iterator;
0072   str_c_iter b = s.cbegin(), e = s.cend();
0073 
0074   if (static_cast<unsigned int>(e - b) < 2u)
0075     return false;
0076 
0077   if (*b == first)
0078     ++b;
0079   else
0080     return false;
0081 
0082   if (*--e != last)
0083     return false;
0084 
0085   // invariant:  we've found all items in [b..boi)
0086   for (str_c_iter  //boi = std::find_if(b, e, is_not_a(sep))
0087            boi = contextual_find_not(b, e, first, sep, last),
0088            eoi;
0089        boi != e
0090        //; boi = std::find_if(eoi, e, is_not_a(sep))
0091        ;
0092        boi = contextual_find_not(eoi, e, first, sep, last)) {
0093     // find end of current item:
0094     //eoi = std::find_if(boi, e, is_a(sep));
0095     eoi = contextual_find(boi, e, first, sep, last);
0096 
0097     // copy the item formed from characters in [boi..eoi):
0098     *dest++ = std::string_view(boi, eoi - boi);
0099   }  // for
0100 
0101   return true;
0102 }  // split< >()
0103 
0104 template <typename FUNC>
0105 bool edm::split(std::string_view s, char first, char sep, char last, FUNC f) {
0106   using str_c_iter = std::string_view::const_iterator;
0107   str_c_iter b = s.cbegin(), e = s.cend();
0108 
0109   if (static_cast<unsigned int>(e - b) < 2u)
0110     return false;
0111 
0112   if (*b == first)
0113     ++b;
0114   else
0115     return false;
0116 
0117   if (*--e != last)
0118     return false;
0119 
0120   // invariant:  we've found all items in [b..boi)
0121   for (str_c_iter boi = contextual_find_not(b, e, first, sep, last), eoi; boi != e;
0122        boi = contextual_find_not(eoi, e, first, sep, last)) {
0123     // find end of current item:
0124     eoi = contextual_find(boi, e, first, sep, last);
0125 
0126     // copy the item formed from characters in [boi..eoi):
0127     if (not f(std::string_view(boi, eoi - boi))) {
0128       return false;
0129     }
0130   }  // for
0131 
0132   return true;
0133 }  // split< >()
0134 
0135 // ----------------------------------------------------------------------
0136 // epilog
0137 
0138 #endif