Sprout の SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION

元々 Sprout を gcc 4.7 で使用する場合に

#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION

をユーザ側で定義しないとコンパイルがされないコード(一時オブジェクトを algorithm で使用する場合等)があったんですが、いつの間にかユーザ側で定義する必要がなくなったみたいです。

[ソース]

// 今まではユーザ側で定義する必要があった
// #define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION

#include <sprout/array.hpp>

int
main(){
    constexpr auto v = sprout::make_array<int>(1, 2, 3, 4);

    // 以前は SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION を定義していなければ
    // 一時オブジェクトを使用する場合にエラーになった
    static_assert(v == sprout::make_array<int>(1, 2, 3, 4), "");

    return 0;
}

[コンパイラ]

  • g++ (GCC) 4.7.0 20111203 (experimental)


また、

#define SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION

を定義する事でその機能を無効にすることが出来るみたいです。

[ソース]

#define SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION

#include <sprout/array.hpp>

int
main(){
    constexpr auto v = sprout::make_array<int>(1, 2, 3, 4);
    
    // error: '& v.sprout::array<int, 4u>::elems[0]' is not a constant expression
    static_assert(v == sprout::make_array<int>(1, 2, 3, 4), "");

    return 0;
}

[コンパイラ]

  • g++ (GCC) 4.7.0 20111203 (experimental)

ちなみに clang では上記の問題がないみたいで無効にしても下記のコードが通りました。

[ソース]

#include <type_traits>

namespace std{

// clang で std::is_literal_type が使えなかったので、とりあえず動くようにするだけ
#ifdef __clang__
    template<typename T>
    struct is_literal_type : std::true_type{};
#endif

}    // namespace std


#define SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION

#include <sprout/array.hpp>

int
main(){
    constexpr auto v = sprout::make_array<int>(1, 2, 3, 4);
    
    // ok
    static_assert(v == sprout::make_array<int>(1, 2, 3, 4), "");

    return 0;
}

ちなみに Sprout.String も動かそうとしたんですが、std::char_traits に引っかかって無理でした。にょろーん

[コンパイラ]

  • clang++ (llvm) 3.1 20120216(trunk)