title: How can I refactor this to use an inline function or template instead of a macro?
body: <p>I have a useful macro here:</p>
  
  <pre><code>#include &lt;algorithm&gt;
  #include &lt;vector&gt;
  #include &lt;string&gt;
  #include &lt;boost/algorithm/string.hpp&gt;
  #include &lt;Windows.h&gt;
  
  namespace Path {
  
  bool Exists(const std::wstring&amp; path)
  {
      DWORD result = GetFileAttributesW(path.c_str());
      return result != INVALID_FILE_ATTRIBUTES;
  }
  
  // THIS IS THE MACRO IN QUESTION!
  #define PATH_PREFIX_RESOLVE(path, prefix, environment) \
  if (boost::algorithm::istarts_with(path, prefix)) { \
      ExpandEnvironmentStringsW(environment, buffer, MAX_PATH); \
      path.replace(0, (sizeof(prefix)/sizeof(wchar_t)) - 1, buffer); \
      if (Exists(path)) return path; \
  }
  
  std::wstring Resolve(std::wstring path)
  {
      using namespace boost::algorithm;
      wchar_t buffer[MAX_PATH];
      trim(path);
      if (path.empty() || Exists(path)) return path;
  
      //Start by trying to see if we have a quoted path
      if (path[0] == L'"') {
          return std::wstring(path.begin() + 1, std::find(path.begin() + 1, path.end(), L'"'));
      }
  
      //Check for those nasty cases where the beginning of the path has no root
      PATH_PREFIX_RESOLVE(path, L"\\", L"");
      PATH_PREFIX_RESOLVE(path, L"?\?\\", L"");
      PATH_PREFIX_RESOLVE(path, L"\\?\\", L"");
      PATH_PREFIX_RESOLVE(path, L"globalroot\\", L"");
      PATH_PREFIX_RESOLVE(path, L"system32\\", L"%systemroot%\\System32\\");
      PATH_PREFIX_RESOLVE(path, L"systemroot\\", L"%systemroot%\\");
  
      static std::vector&lt;std::wstring&gt; pathExts;
      if (pathExts.empty()) {
          #define MAX_ENVVAR 32767
          wchar_t pathext[MAX_ENVVAR];
          DWORD length = GetEnvironmentVariableW(L"PATHEXT", pathext, MAX_ENVVAR);
          if (!length) WindowsApiException::ThrowFromLastError();
          split(pathExts, pathext, std::bind2nd(std::equal_to&lt;wchar_t&gt;(), L';'));
          pathExts.insert(pathExts.begin(), std::wstring());
      }
      std::wstring::iterator currentSpace = path.begin();
      do {
          currentSpace = std::find(currentSpace, path.end(), L' ');
          std::wstring currentPath(path.begin(), currentSpace);
          std::wstring::size_type currentPathLength = currentPath.size();
          typedef std::vector&lt;std::wstring&gt;::const_iterator ExtIteratorType;
          for(ExtIteratorType it = pathExts.begin(); it != pathExts.end(); it++) {
              currentPath.replace(currentPathLength, currentPath.size() - currentPathLength, *it);
              if (Exists(currentPath)) return currentPath;
          }
          if (currentSpace != path.end())
              currentSpace++;
      } while (currentSpace != path.end());
  
      return path;
  }
  
  }
  </code></pre>
  
  <p>It's used about 6 times within the scope of a single function (that's it), but macros seem to have "bad karma" :P</p>
  
  <p>Anyway, the problem here is the <code>sizeof(prefix)</code> part of the macro. If I just replace this with a function taking a <code>const wchar_t[]</code>, then the <code>sizeof()</code> will fail to deliver expected results.</p>
  
  <p>Simply adding a size member doesn't really solve the problem either. Making the user supply the size of the constant literal also results in a mess of duplicated constants at the call site.</p>
  
  <p>Any ideas on this one?</p>