#if !defined(_HARKLIB_BYTESWAP_H_INCLUDED_)
#define _HARKLIB_BYTESWAP_H_INCLUDED_

#include <algorithm>
#include <iterator>

#include <type_traits>

namespace hark
{

template <size_t Size>
void byteswap(void* p);

template <>
void byteswap<2>(void* p) {
    char* pb = reinterpret_cast<char*>(p);
    std::swap(pb[0], pb[1]);
}

template <>
void byteswap<4>(void* p) {
    char* pb = reinterpret_cast<char*>(p);
    std::swap(pb[0], pb[3]);
    std::swap(pb[1], pb[2]);
}

template <>
void byteswap<8>(void* p) {
    char* pb = reinterpret_cast<char*>(p);
    std::swap(pb[0], pb[7]);
    std::swap(pb[1], pb[6]);
    std::swap(pb[2], pb[5]);
    std::swap(pb[3], pb[4]);
}

template <typename T>
T byteswap(T v) {
    T result = v;
    byteswap<sizeof(v)>(reinterpret_cast<void*>(&result));
    return result;
}

template <typename InputIterator>
void byteswap(InputIterator first, InputIterator last) {
    typedef typename std::remove_cv<
        typename std::iterator_traits<InputIterator>::value_type>::type
            input_type;

    for (; first != last; ++first) {
        byteswap<sizeof(input_type)>(reinterpret_cast<void*>(&(*first)));
    }
}

}

#endif // #if !defined(_HARKLIB_BYTESWAP_H_INCLUDED_)

/* end of file */
