/* /////////////////////////////////////////////////////////////////////////////
 * Includes
 */

#include <functional>
#include <algorithm>
#include <windows.h>

/* /////////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _WINSTL_NO_NAMESPACES
 #define winstl_ns_qual(x)          ::winstl::x
 #define winstl_ns_using(x)         using ::winstl::x;
#else
 #define winstl_ns_qual(x)          x
 #define winstl_ns_using(x)
#endif /* !_WINSTL_NO_NAMESPACES */

#ifndef __DMC__
 #define winstl_ns_qual_std(x)      ::std::x
 #define winstl_ns_using_std(x)     using ::std::x;
#else
 #define winstl_ns_qual_std(x)      x
 #define winstl_ns_using_std(x)
#endif /* !__DMC__ */

#ifndef _WINSTL_NO_NAMESPACES
namespace winstl
{
#endif /* _WINSTL_NO_NAMESPACES */

/* /////////////////////////////////////////////////////////////////////////////
 * Classes
 */

// class findvolume_sequence_traits
template <typename C>
struct findvolume_sequence_traits
{
};

// class basic_findvolume_sequence_value_type
template <typename C, typename T>
class basic_findvolume_sequence_value_type;

// class basic_findvolume_sequence_const_iterator
template <typename C, typename T, typename V>
class basic_findvolume_sequence_const_iterator;

// class basic_findvolume_sequence
template <typename C, typename T = findvolume_sequence_traits<C> >
class basic_findvolume_sequence
{
public:
    typedef C                                                           char_type;
    typedef T                                                           traits_type;
    typedef basic_findvolume_sequence<C, T>                             class_type;
    typedef basic_findvolume_sequence_value_type<C, T>                  value_type;
    typedef basic_findvolume_sequence_const_iterator<C, T, value_type>  const_iterator;
    typedef value_type                                                  &reference;
    typedef const value_type                                            &const_reference;

// Construction
public:
    basic_findvolume_sequence();
    ~basic_findvolume_sequence() throw();

// Iteration
public:
    const_iterator  begin() const;
    const_iterator  end() const;

// Not to be implemented
private:
    basic_findvolume_sequence(class_type const &);
    const basic_findvolume_sequence &operator =(class_type const &);
};

/* Typedefs to commonly encountered types. */
typedef basic_findvolume_sequence<char, findvolume_sequence_traits<char> >          findvolume_sequence_a;
typedef basic_findvolume_sequence<wchar_t, findvolume_sequence_traits<wchar_t> >    findvolume_sequence_w;

// class basic_findvolume_sequence_value_type
template <typename C, typename T>
class basic_findvolume_sequence_value_type
{
public:
    typedef C                                           char_type;
    typedef T                                           traits_type;
    typedef basic_findvolume_sequence_value_type<C, T>  class_type;

public:
    basic_findvolume_sequence_value_type();
    basic_findvolume_sequence_value_type(class_type const &rhs);

    class_type &operator =(class_type const &rhs);

    operator const char_type * () const;
};

// class basic_findvolume_sequence_const_iterator
template <typename C, typename T, typename V>
class basic_findvolume_sequence_const_iterator
{
public:
    typedef C                                                   char_type;
    typedef T                                                   traits_type;
    typedef V                                                   value_type;
    typedef basic_findvolume_sequence_const_iterator<C, T, V>   class_type;

public:
    basic_findvolume_sequence_const_iterator();
    basic_findvolume_sequence_const_iterator(class_type const &rhs);

    basic_findvolume_sequence_const_iterator &operator =(class_type const &rhs);

public:
    class_type &operator ++();
    const class_type operator ++(int);
    const value_type operator *() const;
    bool operator ==(class_type const &rhs) const;
    bool operator !=(class_type const &rhs) const;
};

///////////////////////////////////////////////////////////////////////////////

// WALTER, LOOK HERE!!
//
// Set the #if 1 to # if 0 to use the explicit, and I assume incorrect, 
// qualification, which removes the compile error.

#if 1
// original version
template <typename C, typename T>
inline basic_findvolume_sequence_value_type<C, T>::basic_findvolume_sequence_value_type()
{
}
#else
// Explicitly qualified version
template <typename C, typename T>
inline winstl::basic_findvolume_sequence_value_type<C, T>::basic_findvolume_sequence_value_type()
{
}
#endif /* 1 */

/* ////////////////////////////////////////////////////////////////////////// */

#ifndef _WINSTL_NO_NAMESPACES
} // namespace winstl
#endif /* _WINSTL_NO_NAMESPACES */

/* ////////////////////////////////////////////////////////////////////////// */



#include <windows.h>
#include <stdio.h>
#include <wchar.h>

#ifndef __BORLANDC__
HANDLE (WINAPI *FindFirstVolumeA)(
  LPSTR lpszVolumeName,   // output buffer
  DWORD cchBufferLength    // size of output buffer
);


HANDLE (WINAPI *FindNextVolumeA)(
  HANDLE hFindVolume,      // volume search handle
  LPSTR lpszVolumeName,   // output buffer
  DWORD cchBufferLength    // size of output buffer
);

HANDLE (WINAPI *FindVolumeClose)(
    HANDLE hFindVolume
    );
#endif /* __BORLANDC__ */


template <typename C>
struct print_path
	: winstl_ns_qual_std(unary_function)<const winstl_ns_qual(basic_findvolume_sequence)<C>::value_type &, void>
{
public:
	void operator ()(const winstl_ns_qual(basic_findvolume_sequence)<C>::value_type &value);
};

#ifndef __DMC__
template<>
#endif /* __DMC__ */
void print_path<char>::operator ()(const winstl_ns_qual(basic_findvolume_sequence)<char>::value_type &value)
{
	fprintf(stdout, "%s\n", (const char *)value);
}




int main(int /* argc */, char ** /*argv*/)
{
	winstl_ns_qual(findvolume_sequence_a)	volumes_a;

	winstl_ns_qual_std(for_each)(volumes_a.begin(), volumes_a.end(), print_path<char>());

    return 0;
}
