diff DEPENDENCIES/generic/include/boost/wave/util/cpp_include_paths.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/wave/util/cpp_include_paths.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,553 @@
+/*=============================================================================
+    Boost.Wave: A Standard compliant C++ preprocessor library
+
+    http://www.boost.org/
+
+    Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
+    Software License, Version 1.0. (See accompanying file
+    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+#if !defined(CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)
+#define CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED
+
+#include <string>
+#include <list>
+#include <utility>
+
+#include <boost/wave/wave_config.hpp>
+#include <boost/wave/util/filesystem_compatibility.hpp>
+
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#endif
+
+#if BOOST_WAVE_SERIALIZATION != 0
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/utility.hpp>
+#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
+#include <boost/serialization/split_free.hpp>
+#endif
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+// this must occur after all of the includes and before any code appears
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_PREFIX
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace wave { namespace util {
+
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+///////////////////////////////////////////////////////////////////////////////
+//  Tags for accessing both sides of a bidirectional map
+struct from {};
+struct to {};
+
+///////////////////////////////////////////////////////////////////////////////
+//  The class template bidirectional_map wraps the specification
+//  of a bidirectional map based on multi_index_container.
+template<typename FromType, typename ToType>
+struct bidirectional_map
+{
+    typedef std::pair<FromType, ToType> value_type;
+
+#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) || \
+    (defined(BOOST_MSVC) && \
+        ( (BOOST_MSVC < 1300) || (BOOST_MSVC == 1600) )) || \
+    (defined(BOOST_INTEL_CXX_VERSION) && \
+        (defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 700))) 
+
+    BOOST_STATIC_CONSTANT(unsigned, from_offset = offsetof(value_type, first));
+    BOOST_STATIC_CONSTANT(unsigned, to_offset   = offsetof(value_type, second));
+
+    typedef boost::multi_index::multi_index_container<
+        value_type,
+        boost::multi_index::indexed_by<
+            boost::multi_index::ordered_unique<
+                boost::multi_index::tag<from>, 
+                boost::multi_index::member_offset<value_type, FromType, from_offset> 
+            >,
+            boost::multi_index::ordered_non_unique<
+                boost::multi_index::tag<to>, 
+                boost::multi_index::member_offset<value_type, ToType, to_offset> 
+            >
+        >
+    > type;
+
+#else
+
+  typedef boost::multi_index::multi_index_container<
+      value_type,
+      boost::multi_index::indexed_by<
+          boost::multi_index::ordered_unique<
+              boost::multi_index::tag<from>,
+              boost::multi_index::member<value_type, FromType, &value_type::first> 
+          >,
+          boost::multi_index::ordered_non_unique<
+              boost::multi_index::tag<to>,  
+              boost::multi_index::member<value_type, ToType, &value_type::second> 
+          >
+      >
+  > type;
+
+#endif
+};
+#endif // BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+
+#if BOOST_WAVE_SERIALIZATION != 0
+struct load_filepos
+{
+    static unsigned int get_line() { return 0; }
+    static unsigned int get_column() { return 0; }
+    static std::string get_file() { return "<loading-state>"; }
+};
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  include_paths - controlling the include path search order
+//
+//  General notes:
+//
+//      Any directories specified with the 'add_include_path()' function before 
+//      the function 'set_sys_include_delimiter()' is called are searched only 
+//      for the case of '#include "file"' directives, they are not searched for 
+//      '#include <file>' directives. If additional directories are specified 
+//      with the 'add_include_path()' function after a call to the function 
+//      'set_sys_include_delimiter()', these directories are searched for all 
+//      '#include' directives. 
+//
+//      In addition, a call to the function 'set_sys_include_delimiter()' 
+//      inhibits the use of the current directory as the first search directory 
+//      for '#include "file"' directives. Therefore, the current directory is 
+//      searched only if it is requested explicitly with a call to the function
+//      'add_include_path(".")'. 
+//
+//      Calling both functions, the 'set_sys_include_delimiter()' and 
+//      'add_include_path(".")' allows you to control precisely which 
+//      directories are searched before the current one and which are searched 
+//      after.
+//
+///////////////////////////////////////////////////////////////////////////////
+class include_paths
+{
+private:
+    typedef std::list<std::pair<boost::filesystem::path, std::string> > 
+        include_list_type;
+    typedef include_list_type::value_type include_value_type;
+
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+    typedef bidirectional_map<std::string, std::string>::type 
+        pragma_once_set_type;
+#endif
+
+public:
+    include_paths()
+    :   was_sys_include_path(false),
+        current_dir(initial_path()),
+        current_rel_dir(initial_path())
+    {}
+    
+    bool add_include_path(char const *path_, bool is_system = false)
+    {
+        return add_include_path(path_, (is_system || was_sys_include_path) ? 
+            system_include_paths : user_include_paths);
+    }
+    void set_sys_include_delimiter() { was_sys_include_path = true; }
+    bool find_include_file (std::string &s, std::string &dir, bool is_system, 
+        char const *current_file) const;
+    void set_current_directory(char const *path_);
+    boost::filesystem::path get_current_directory() const 
+        { return current_dir; }
+
+protected:
+    bool find_include_file (std::string &s, std::string &dir, 
+        include_list_type const &pathes, char const *) const;
+    bool add_include_path(char const *path_, include_list_type &pathes_);
+
+private:
+    include_list_type user_include_paths;
+    include_list_type system_include_paths;
+    bool was_sys_include_path;          // saw a set_sys_include_delimiter()
+    boost::filesystem::path current_dir;
+    boost::filesystem::path current_rel_dir;
+
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+public:
+    bool has_pragma_once(std::string const &filename)
+    {
+        using boost::multi_index::get;
+        return get<from>(pragma_once_files).find(filename) != pragma_once_files.end();
+    }
+    bool add_pragma_once_header(std::string const &filename, 
+        std::string const& guard_name)
+    {
+        typedef pragma_once_set_type::value_type value_type;
+        return pragma_once_files.insert(value_type(filename, guard_name)).second;
+    }
+    bool remove_pragma_once_header(std::string const& guard_name)
+    {
+        typedef pragma_once_set_type::index_iterator<to>::type to_iterator;
+        typedef std::pair<to_iterator, to_iterator> range_type;
+        
+        range_type r = pragma_once_files.get<to>().equal_range(guard_name);
+        if (r.first != r.second) {
+            using boost::multi_index::get;
+            get<to>(pragma_once_files).erase(r.first, r.second);
+            return true;
+        }
+        return false;
+    }
+
+private:
+    pragma_once_set_type pragma_once_files;
+#endif
+
+#if BOOST_WAVE_SERIALIZATION != 0
+public:
+    BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
+    BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);
+
+private:
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void save(Archive & ar, const unsigned int version) const
+    {
+        using namespace boost::serialization;
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+        ar & make_nvp("pragma_once_files", pragma_once_files);
+#endif
+        ar & make_nvp("user_include_paths", user_include_paths);
+        ar & make_nvp("system_include_paths", system_include_paths);
+        ar & make_nvp("was_sys_include_path", was_sys_include_path);
+    }
+    template<typename Archive>
+    void load(Archive & ar, const unsigned int loaded_version)
+    {
+        using namespace boost::serialization;
+        if (version != (loaded_version & ~version_mask)) {
+            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
+                "cpp_include_path state version", load_filepos());
+            return;
+        }
+
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+        ar & make_nvp("pragma_once_files", pragma_once_files);
+#endif
+        // verify that the old include paths match the current ones
+        include_list_type user_paths, system_paths;
+        ar & make_nvp("user_include_paths", user_paths);
+        ar & make_nvp("system_include_paths", system_paths);
+
+        if (user_paths != user_include_paths)
+        {
+            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
+                "user include paths", load_filepos());
+            return;
+        }
+        if (system_paths != system_include_paths)
+        {
+            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
+                "system include paths", load_filepos());
+            return;
+        }
+
+        ar & make_nvp("was_sys_include_path", was_sys_include_path);
+    }
+    BOOST_SERIALIZATION_SPLIT_MEMBER()
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  Add an include path to one of the search lists (user include path or system 
+//  include path).
+inline
+bool include_paths::add_include_path (
+    char const *path_, include_list_type &pathes_)
+{
+    namespace fs = boost::filesystem;
+    if (path_) {
+    fs::path newpath = util::complete_path(create_path(path_), current_dir);
+
+        if (!fs::exists(newpath) || !fs::is_directory(newpath)) {
+        // the given path does not form a name of a valid file system directory
+        // item
+            return false;
+        }
+
+        pathes_.push_back (include_value_type(newpath, path_));
+        return true;
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  Find an include file by traversing the list of include directories
+inline
+bool include_paths::find_include_file (std::string &s, std::string &dir, 
+    include_list_type const &pathes, char const *current_file) const
+{
+    namespace fs = boost::filesystem;
+    typedef include_list_type::const_iterator const_include_list_iter_t;
+
+    const_include_list_iter_t it = pathes.begin();
+    const_include_list_iter_t include_paths_end = pathes.end();
+
+#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0    
+    if (0 != current_file) {
+    // re-locate the directory of the current file (#include_next handling)
+
+    // #include_next does not distinguish between <file> and "file"
+    // inclusion, nor does it check that the file you specify has the same
+    // name as the current file.  It simply looks for the file named, starting
+    // with the directory in the search path after the one where the current
+    // file was found.
+
+        fs::path file_path (create_path(current_file));
+        for (/**/; it != include_paths_end; ++it) {
+            fs::path currpath (create_path((*it).first.string()));
+            if (std::equal(currpath.begin(), currpath.end(), file_path.begin())) 
+            {
+                ++it;     // start searching with the next directory
+                break;
+            }
+        }
+    }
+#endif
+
+    for (/**/; it != include_paths_end; ++it) {
+        fs::path currpath (create_path(s));
+        if (!currpath.has_root_directory()) {
+            currpath = create_path((*it).first.string());
+            currpath /= create_path(s);      // append filename
+        }
+        
+        if (fs::exists(currpath)) {
+            fs::path dirpath (create_path(s));
+            if (!dirpath.has_root_directory()) {
+                dirpath = create_path((*it).second);
+                dirpath /= create_path(s);
+            }
+
+            dir = dirpath.string();
+            s = normalize(currpath).string();    // found the required file
+            return true;
+        }
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  Find an include file by searching the user and system includes in the 
+//  correct sequence (as it was configured by the user of the driver program)
+inline bool 
+include_paths::find_include_file (std::string &s, std::string &dir, 
+    bool is_system, char const *current_file) const
+{
+    namespace fs = boost::filesystem;
+
+// if not system include (<...>), then search current directory first
+    if (!is_system) {
+        if (!was_sys_include_path) {  // set_sys_include_delimiter() not called
+        // first have a look at the current directory
+            fs::path currpath (create_path(s));
+            if (!currpath.has_root_directory()) {
+                currpath = create_path(current_dir.string());
+                currpath /= create_path(s);
+            }
+            
+            if (fs::exists(currpath) && 0 == current_file) {
+            // if 0 != current_path (#include_next handling) it can't be
+            // the file in the current directory
+                fs::path dirpath (create_path(s));
+                if (!dirpath.has_root_directory()) {
+                    dirpath = create_path(current_rel_dir.string());
+                    dirpath /= create_path(s);
+                }
+
+                dir = dirpath.string();
+                s = normalize(currpath).string();    // found in local directory
+                return true;
+            }   
+
+        // iterate all user include file directories to find the file
+            if (find_include_file(s, dir, user_include_paths, current_file))
+                return true;
+
+        // ... fall through
+        }
+        else {
+        //  if set_sys_include_delimiter() was called, then user include files
+        //  are searched in the user search path only
+            return find_include_file(s, dir, user_include_paths, current_file);
+        }
+        
+    // if nothing found, fall through
+    // ...
+    }
+
+// iterate all system include file directories to find the file
+    return find_include_file (s, dir, system_include_paths, current_file);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  Set current directory from a given file name
+
+inline bool
+as_relative_to(boost::filesystem::path const& path, 
+    boost::filesystem::path const& base, boost::filesystem::path& result) 
+{
+    if (path.has_root_path()) {
+        if (path.root_path() == base.root_path()) 
+            return as_relative_to(path.relative_path(), base.relative_path(), result);
+
+        result = path;    // that's our result
+    } 
+    else {
+        if (base.has_root_path()) {
+            // cannot find relative path from a relative path and a rooted base
+            return false;
+        } 
+        else {
+            typedef boost::filesystem::path::const_iterator path_iterator;
+            path_iterator path_it = path.begin();
+            path_iterator base_it = base.begin();
+            while (path_it != path.end() && base_it != base.end() ) {
+                if (*path_it != *base_it) 
+                    break;
+                ++path_it; ++base_it;
+            }
+
+            for (/**/; base_it != base.end(); ++base_it)
+                result /= "..";
+
+            for (/**/; path_it != path.end(); ++path_it)
+                result /= *path_it;
+        }
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+inline
+void include_paths::set_current_directory(char const *path_)
+{
+    namespace fs = boost::filesystem;
+    
+    fs::path filepath (create_path(path_));
+    fs::path filename = util::complete_path(filepath, current_dir);
+    if (fs::exists(filename) && fs::is_directory(filename)) {
+        current_rel_dir.clear();
+        if (!as_relative_to(filepath, current_dir, current_rel_dir))
+            current_rel_dir = filepath;
+        current_dir = filename;
+    }
+    else {
+        current_rel_dir.clear();
+        if (!as_relative_to(branch_path(filepath), current_dir, current_rel_dir))
+            current_rel_dir = branch_path(filepath);
+        current_dir = branch_path(filename);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}}}   // namespace boost::wave::util
+
+#if BOOST_WAVE_SERIALIZATION != 0
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace serialization {
+
+///////////////////////////////////////////////////////////////////////////////
+//  Serialization support for boost::filesystem::path
+template<class Archive>
+inline void save (Archive & ar, boost::filesystem::path const& p, 
+    const unsigned int /* file_version */)
+{
+    using namespace boost::serialization;
+    std::string path_str(p.native_file_string());
+    ar & make_nvp("filepath", path_str);
+}
+
+template<class Archive>
+inline void load (Archive & ar, boost::filesystem::path &p,
+    const unsigned int /* file_version */)
+{
+    using namespace boost::serialization;
+    std::string path_str;
+    ar & make_nvp("filepath", path_str);
+    p = wave::util::create_path(path_str);
+}
+
+// split non-intrusive serialization function member into separate
+// non intrusive save/load member functions
+template<class Archive>
+inline void serialize (Archive & ar, boost::filesystem::path &p,
+    const unsigned int file_version)
+{
+    boost::serialization::split_free(ar, p, file_version);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  Serialization support for the used multi_index
+template<class Archive>
+inline void save (Archive & ar,
+    const typename boost::wave::util::bidirectional_map<
+        std::string, std::string
+    >::type &t,
+    const unsigned int /* file_version */)
+{
+    boost::serialization::stl::save_collection<
+        Archive, 
+        typename boost::wave::util::bidirectional_map<
+            std::string, std::string
+        >::type
+    >(ar, t);
+}
+
+template<class Archive>
+inline void load (Archive & ar,
+    typename boost::wave::util::bidirectional_map<std::string, std::string>::type &t,
+    const unsigned int /* file_version */)
+{
+    typedef typename boost::wave::util::bidirectional_map<
+            std::string, std::string
+        >::type map_type;
+    boost::serialization::stl::load_collection<
+        Archive, map_type,
+        boost::serialization::stl::archive_input_unique<Archive, map_type>,
+        boost::serialization::stl::no_reserve_imp<map_type>
+    >(ar, t);
+}
+
+// split non-intrusive serialization function member into separate
+// non intrusive save/load member functions
+template<class Archive>
+inline void serialize (Archive & ar, 
+    typename boost::wave::util::bidirectional_map<
+        std::string, std::string
+    >::type &t,
+    const unsigned int file_version)
+{
+    boost::serialization::split_free(ar, t, file_version);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}}  // namespace boost::serialization
+
+BOOST_CLASS_VERSION(boost::wave::util::include_paths, 
+    boost::wave::util::include_paths::version);
+
+#endif  // BOOST_WAVE_SERIALIZATION != 0
+
+// the suffix header occurs after all of the code
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // !defined(CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)