Tessil / ordered-map

C++ hash map and hash set which preserve the order of insertion
MIT License
512 stars 66 forks source link

Visual Studio 2017 and ordered-map #12

Closed DJuego closed 6 years ago

DJuego commented 6 years ago

Hi! Thank you for your numerous contributions, @Tessil !!

I know you are familiarized with nlohmann/json and Tessil/ordered-map interaction:

https://github.com/Tessil/ordered-map/issues/9 https://github.com/nlohmann/json/issues/546

I need a ordered json and i am using your way. I have test this code in MinGW gcc 7.30 and it works!

This sample is the adaptacion of nlohmann/json sample to Tessil/ordered-map, I tried to follow your instruction. Sorry for my inexperience. :-|

#include <string>
#include <iostream>
#include <nlohmann/json.hpp>
#include <tsl/ordered_map.h>
#include <tsl/ordered_set.h>

template<class Key, class T, class Ignore, class Allocator,
    class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>

    using ordered_map = tsl::ordered_map<Key, T, Hash, KeyEqual,
    typename std::allocator_traits<Allocator>::template
    rebind_alloc<std::pair<Key, T>>>;

using json = nlohmann::basic_json<ordered_map>; //It only works in MinGW 7.3.0 (the json is ordered :-))

//using json = nlohmann::json; //It works in MSVC2017 and MinGW 7.3.0

namespace ns {

    // a simple struct to model a person
    struct person {
        std::string name;
        std::string address;
        int age;
    };
//}

//namespace ns {

    void to_json(json& j, const person& p) {
        j = json{ { "name", p.name },{ "address", p.address },{ "age", p.age } };
    }

    void from_json(const json& j, person& p) {
        p.name = j.at("name").get<std::string>();
        p.address = j.at("address").get<std::string>();
        p.age = j.at("age").get<int>();
    }
} // namespace ns

int main()
{
    // create a person
    ns::person p{ "Ned Flanders", "744 Evergreen Terrace", 60 };

    // conversion: person -> json
    json j = p;

    std::cout << j << std::endl;
    // {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

    // conversion: json -> person
    ns::person p2 = j;

    // that's it
    //assert(p == p2);
}

I get the next error in Visual Studio 2017( 15.7.1 ) (Windows 10 x64)

1>------ Build started: Project: prueba, Configuration: Debug x64 ------
1>main.cpp
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\utility(293): error C2079: 'std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>::second' uses undefined class 'nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>'
1>        with
1>        [
1>            StringType=std::string
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\deque(967): note: see reference to class template instantiation 'std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>' being compiled
1>        with
1>        [
1>            StringType=std::string
1>        ]
1>p:\mis-proyectos\profesional\prueba\prueba\prueba\tsl\ordered_hash.h(215): note: see reference to class template instantiation 'std::deque<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,Allocator>' being compiled
1>        with
1>        [
1>            StringType=std::string,
1>            Allocator=std::allocator<std::pair<std::string,nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>
1>        ]
1>p:\mis-proyectos\profesional\prueba\prueba\prueba\tsl\ordered_map.h(106): note: see reference to class template instantiation 'tsl::detail_ordered_hash::ordered_hash<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,tsl::ordered_map<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,std::hash<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,std::equal_to<Key>,std::allocator<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>,std::deque<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,Allocator>>::KeySelect,tsl::ordered_map<Key,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,std::hash<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,std::equal_to<Key>,Allocator,std::deque<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,Allocator>>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer>' being compiled
1>        with
1>        [
1>            StringType=std::string,
1>            Key=std::string,
1>            Allocator=std::allocator<std::pair<std::string,nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>,
1>            Hash=std::hash<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,
1>            KeyEqual=std::equal_to<std::string>,
1>            ValueTypeContainer=std::deque<std::pair<std::string,nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,std::allocator<std::pair<std::string,nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>>
1>        ]
1>p:\mis-proyectos\profesional\prueba\prueba\prueba\nlohmann\json.hpp(12791): note: see reference to class template instantiation 'tsl::ordered_map<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,std::hash<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,std::equal_to<Key>,std::allocator<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>,std::deque<std::pair<StringType,nlohmann::basic_json<ordered_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,Allocator>>' being compiled
1>        with
1>        [
1>            StringType=std::string,
1>            Key=std::string,
1>            Allocator=std::allocator<std::pair<std::string,nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>
1>        ]
1>p:\mis-proyectos\profesional\prueba\prueba\prueba\main.cpp(36): note: see reference to class template instantiation 'nlohmann::basic_json<ordered_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>' being compiled
1>Done building project "prueba.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Could you help me? Thanks!

DJuego

Tessil commented 6 years ago

Hi, thank you for the report.

Could you try with

template<class Key, class T, class Ignore, class Allocator,
     class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>, 
         class ValueTypeContainer = std::vector<std::pair<Key, T>>>
using ordered_map = 
tsl::ordered_map<Key, T, Hash, KeyEqual,
             typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<Key, T>>,
                 ValueTypeContainer>;

It seems to be related to Issue #2, as the json is also a recursive container in the end.

DJuego commented 6 years ago

It works!! Thank you very much!

I can confirm it in Visual Studio 2017 (15.7.1) and MinGW (gcc 7.3.0) (x86_64-7.3.0-release-posix-seh-rt_v5-rev0)

DJuego

Tessil commented 6 years ago

Glad it works. I updated my post in the issue of nlohmann library to reflect the valid solution.